在以下代码中,Child
的构造函数降低了从public
到private
的可见性,这是允许的。继承的方法(例如test()
)不能降低可见性。为什么Java以这种方式运行?
class Parent {
public Parent(){}
public void test()
{
System.out.print("parent test executed!");
}
}
class Child extends Parent{
private Child(){}
private void test(){
System.out.print("child test executed!");
}
}
答案 0 :(得分:13)
构建器不是继承的,因此Child()
不会覆盖Parent()
。
至于方法,如果你有(如果Child()
是public
)
Parent p = new Child();
p.test();
如果允许,这将调用private
方法。因此,不允许在覆盖时缩小访问范围。
答案 1 :(得分:1)
扩展课程时,您声明您的课程是父课程的延伸(“IS-A”关系)。这意味着你的类将拥有你父类的所有方法。这与在java中实现接口相同,除了从父级获取方法定义(和字段),而不仅仅是在接口中声明的方法。在接口中,构造函数不存在,因为它们不是方法。构造函数是特殊的,因为它们完全属于它们声明的类。他们宣称如何只建造自己。
为了构造一个对象,你必须知道对象类。
class A {
private message;
private A() {
message = "You created an A";
}
public A(String message) {
this.message = message;
}
public void printMessage() {
System.out.println(message);
}
public static A createAnA() {
return new A();
}
}
class B extends A {
public B() {
super("You created a B");
}
}
A anA = new B(); // This will work
A anotherA = new A(); // This is not allowed as the constructor is private
A yetAnotherA = A.createAnA(); // This works too
因此,当我们构造B时,我们可以说它是A.即使构造函数A是私有的,这也是因为构造函数不是接口的一部分。当我们将它分配给类型A的字段时,我们唯一要说的是它具有在A中声明的方法。在这种情况下printMessage
和createAnA
。
这就是为什么你可以在不改变类定义的情况下使构造函数成为私有的。现在,为什么在覆盖父母签名时不允许将该方法设为私有。这导致[class].method()
的定义不同。假设您可以将您的方法设为私有。假设您在B类中声明了printMssage。您的理由是您希望该方法仅供您在方法中使用,并且您希望在外部调用时使用父级printMessage。现在,你在B类中编写了这样的方法。
public void adjustMessage(String additional) {
message = getMessage() + additional();
}
将执行哪个版本的get消息?您的私人或您父母的公众? Java调度程序当然会选择公共调度程序,因为它是在接口中声明的那个。所以我们看看这个例子,我们可以看到你是否确实让你的方法具有不同的低权限,你的方法永远不会被派遣,这会让读者感到困惑。
这是一个非常好的问题。