class Base {
public void add() {
System.out.println("Base ADD");
}
void subtract() {
throw new UnsupportedOperationException("Not yet implemented");
}
}
class Child extends Base {
public void add(){
System.out.println("Child ADD");
}
public void subtract() {
System.out.println("Child Subtract");
}
}
class MainClass {
public static void main(String args[]) {
Base b1 = new Base();
Base b2 = new Child();
Child b3 = new Child();
b1.add();
b2.subtract();
b2.add();
b3.subtract();
}
}
Run Code Online (Sandbox Code Playgroud)
我对上面的代码感到有些困惑.让我最困惑的是
Base b2 = new Child();
Run Code Online (Sandbox Code Playgroud)
和
b2.subtract();
Run Code Online (Sandbox Code Playgroud)
我所理解的是在编译时编译器检查天气Base类是否有subtract()方法,然后在运行时运行时多态性发生,因为对象是类型Child.
问题是我们如何或在何处使用这条线即 Base b2 = new Child();
在什么情况下我们应该使用它?请帮助,这将是伟大的!
Jon*_*eet 10
看看声明的两个部分:
Base b2
Run Code Online (Sandbox Code Playgroud)
声明一个名为b2type 的变量Base.如果引用为null或引用的实例Base或子类,则可以为该变量分配引用Base.
然后
new Child()
Run Code Online (Sandbox Code Playgroud)
创建一个新的实例Child.Child是的子类Base,因此您可以将构造函数返回的引用分配给b2变量.
现在,您只能"看到" Basethrough的成员b2,即使实际值是指Child执行时的实例.但是任何Base被覆盖的方法Child都会在被调用时使用被覆盖的版本......所以当你打电话时
b2.subtract();
Run Code Online (Sandbox Code Playgroud)
JVM找出引用的对象的实际类型b2,并使用该类的实现subtract- 在这种情况下,打印"Child Subtract"的方法.
编辑:你特别问过你可以在哪里使用这种东西,以及它如何帮助......
您可以在任何时候声明更通用类型的变量(超类或接口)时使用它,但是为它分配一个值,该值恰好是接口的子类或实现.另一个例子:
List<String> strings = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)
以一般方式声明变量的主要优点是您保持灵活性 - 稍后您可以从使用更改ArrayList<T>为其他实现List<T>,并且代码应该仍然有效.你基本上是在说,"我只需要提供的成员和保证List<T>- 我使用的事实ArrayList<T>是偶然的."
一个类似的例子是决定一个方法应该返回什么类型 - 通常你只想声明你返回一个通用类型(或接口),即使实现知道它返回哪个具体类型.这隐藏了实现细节,允许您稍后更改它们.
| 归档时间: |
|
| 查看次数: |
965 次 |
| 最近记录: |