为什么Java中不允许使用较弱的重写函数?

时间:2012-03-19 07:57:32

标签: java access-modifiers

我有以下代码:

public class Library {

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

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

}

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

5 个答案:

答案 0 :(得分:5)

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

new Book().myFunction()             // clearly, no access

((Library)new Book()).myFunction()  // now ... access?

问题实际上归结为myFunction 虚拟;调用的方法取决于运行时类型,而不是表达式的静态类型。 (我相信C#实际上允许使用new修饰符的非虚方法。)

答案 1 :(得分:0)

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

因此,如果您返回像Library test = getALibraryObject();这样的书,您会看到该方法无法在某个对象中受到保护而在其他对象中无法保护。

答案 2 :(得分:0)

你的例子有点不对,因为一本书不是图书馆。但是让我们考虑一下Car and Truck。

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

答案 3 :(得分:0)

我们假设有一个班级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可以访问Library的{​​{1}}方法,但无法访问read的{​​{1}}方法,这很奇怪,是吗?

答案 4 :(得分:-1)

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