其实我的问题已经回答了,但我无法理解。这是一段代码片段:
public class Superclass {
public static void main (String[] args){
Superclass obj = new Subclass();
obj.doSomething(); #prints "from Superclass"
}
private void doSomething(){System.out.println("from Superclass");}
}
class Subclass extends Superclass {
private void doSomething(){System.out.println("from Subclass");}
}
打印出:“来自超类”
由于对象obj的引用类型是SuperClass,因此调用 doSomething()尝试访问SuperClass中定义的私有方法 本身(私有方法不能被覆盖)。就像doSomething()一样 在SuperClass中可访问,主要方法可以调用doSomething() 没有给出任何错误。
据我所知,调用方法的方式是这样的:(也许我完全错了):
对象的实例仅存储数据本身,当我调用实例方法时,Java会查看引用变量的类型,并从该类的类中调用该方法。 (这对我来说似乎合乎逻辑,并解释了为什么上面的代码打印“来自Superclass”)
但是将第一个doSomething()
方法中的访问修饰符更改为受保护会让我感到困惑,因为我无法理解Java如何知道如果引用类型是SuperClass
而不是SubClass
则存在重写{1}}。覆盖是否也改变了Superclass
中的方法?
或者我对方法调用和覆盖如何工作完全错了?
我真的很感激如果有人可以帮我解释我错过了什么。
答案 0 :(得分:2)
私有方法以及静态方法和所有变量都无法覆盖,可以隐藏。因此,您需要将方法的访问修饰符从私有更改为任何其他访问修饰符。
N.B:覆盖方法时要遵循一些协议;如果不能比被覆盖的方法更易于访问,则子类中定义的方法的访问修饰符必须具有相同的访问级别。返回类型必须是协变等...
答案 1 :(得分:0)
既然你已经定义了" doSomething"作为私有方法,您的覆盖不起作用。将其更改为public或protected,然后查看输出。
要更好地理解它,请将Subclass移动到另一个java文件中。现在告诉我,你能从一个对象句柄进行私有方法调用吗?
答案 2 :(得分:0)
重写方法的功能只是定义使用继承执行相同方法的另一种方法。
不,压倒根本不会改变超级班级(除非你用反思做了一些奇怪的事情,但这是另一个故事)。
私有关键字仅在类本身可以"参见"时使用。方法。另一方面,受保护的关键字完全用于继承:类及其子级可以看到该方法。这就是为什么你只能覆盖受保护的方法。