1. 但这还不是全部。
假设该类Cow
有一个printAll()
调用另外两个方法的方法。然后代码将像这样工作:
代码 | 描述 |
---|---|
|
|
|
屏幕输出将是:
|
注意,在对象上调用类printAll()
中的方法时,使用的是类中的方法,而不是方法中的方法。Cow
Whale
printName
Whale
Cow
主要的不是编写方法的类,而是调用方法的对象的类型(类)。
只有非静态方法可以被继承和覆盖。静态方法不被继承,因此不能被覆盖。
这是Whale
应用继承和方法覆盖后类的样子:
|
这是Whale 在应用继承和方法重写之后该类的样子: 我们不知道任何旧printName 方法。 |
2. 类型转换
这里还有更有趣的一点。因为一个类继承了其父类的所有方法和数据,所以对子类对象的引用可以存储在(分配给)类型与父类(以及父类的父类等)相同的变量中 -一直到班级Object
)。例子:
代码 | 描述 |
---|---|
|
屏幕输出将是:
|
|
屏幕输出将是:
|
|
屏幕输出将是:
方法 toString() 继承自Object 类 |
这是一个非常有价值的属性:稍后您将了解如何在实践中使用它。
3. 调用对象的方法
当在变量上调用方法时,实际上是在对象上调用该方法。这种机制称为动态方法分派。
这是它的样子:
代码 | 描述 |
---|---|
|
屏幕输出将是:
|
|
屏幕输出将是:
|
printName()
请注意,被调用方法的具体实现——是类中的方法Cow
还是类中的方法Whale
——不是由变量的类型决定的,而是由变量引用的对象的类型决定的。
变量Cow
存储一个对象的引用Whale
,printName()
类中定义的方法Whale
就是被调用的。
这不是很明显。记住主要规则:
可在变量上调用的方法集由变量的类型决定。 调用的具体方法实现由变量引用的对象的类型/类决定。
你会一直遇到这个,所以你越早记住越好。
GO TO FULL VERSION