【问题标题】:Why weaker overridden functions are not allowed in Java?为什么 Java 中不允许使用较弱的覆盖函数?
【发布时间】:2012-03-19 07:57:31
【问题描述】:

我有以下代码:

public class Library {

    public void myFunction() {
        // do something
    }
}
public class Book extends Library{

    protected void myFunction() { // Error here
        // do something
    }

}

上面的代码有错误,因为 Book 类试图用较弱的访问修饰符覆盖 supper 类的函数。我知道这是 Java 的规则。但我很好奇为什么会这样?它可能会导致什么问题?

【问题讨论】:

    标签: java access-modifiers


    【解决方案1】:

    考虑,从一个完全不同的包:

    new Book().myFunction()             // clearly, no access
    
    ((Library)new Book()).myFunction()  // now ... access?
    

    问题真的归结为myFunction虚拟的;调用的方法取决于 runtime-type 而不是表达式的静态类型。 (我相信 C# 实际上会允许这种带有 new 修饰符的非虚拟方法。)

    【讨论】:

      【解决方案2】:

      当然,因为如果有人给了图书馆,那么他应该打电话给myFunction,因为它的签名是公开的。

      因此,如果您返回像 Library test = getALibraryObject(); 这样的书,您会发现该方法在某些对象中无法保护,而在其他对象中则没有。

      【讨论】:

        【解决方案3】:

        您的示例有点偏离,因为一本书不是图书馆。但是让我们考虑一下汽车和卡车。

        public class Car {
            public start() {}
        }
        
        public class Truck extends Car {
            protected start() {}
        }
        
        Car c = new Truck(); // should be possible yes?
        c.start(); // this is why you cannot change access modifiers in sub classes
        

        【讨论】:

          【解决方案4】:

          假设有一个类Reader

          public class Reader {
            private final Library library;
          
            public Reader(Library library) {
              this.library = library;
            }
          
            public void read() {
              library.read();
            }
          }
          

          使用Book 的实例初始化:

          Reader reader = new Reader(new Book());
          

          然后,读者将无法阅读一本书,因为它的 read 方法在 Reader 的上下文中不可见。 Reader可以访问Libraryread方法,但是不能访问Bookread方法,很奇怪吧?

          【讨论】:

            【解决方案5】:

            这是面向对象语言的规则。 你不能绑定覆盖方法的访问控制。 如果覆盖的方法受到保护,那么您可以将其作为公共覆盖,但反之亦然是不可能的

            【讨论】:

            • 这不是“面向对象语言”的规则。它与OO无关。最初指定的安全性不应该是可破坏的,这是一个基本原则。
            • 原则和规则有什么区别??
            • 正如 EJP 所说,它与面向对象没有任何关系。此外,正如 pst 所说,在 C# 中,可以使用“new”关键字执行类似的操作。 C# 也是面向对象的。
            • 区别不在于“原则”和“规则”,区别在于“面向对象语言”和“基本原则……[安全]”。坦率地说,我觉得这很明显,就像你原来帖子中的错误一样。
            猜你喜欢
            • 2011-02-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-14
            • 2014-11-03
            • 1970-01-01
            • 2015-03-21
            相关资源
            最近更新 更多