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();
}
}我对上面的代码有点迷惑。最让我困惑的一句话是
Base b2 = new Child();和
b2.subtract();我所理解的是,在编译时,编译器检查Base类是否有subtract()方法,然后在运行时,当object的类型为Child时,就会发生多态性。
问题是我们如何或在哪里使用这一行,即Base b2 = new Child();
我们应该在什么情况下使用它?请帮帮忙,那就太好了!
发布于 2010-12-15 16:16:55
看一下声明的两个部分:
Base b2它声明了一个名为b2的Base类型的变量。如果引用为空,或者引用Base的实例或Base的子类,则可以为该变量分配引用。
然后
new Child()创建Child的新实例。Child是Base的子类,因此可以将构造函数返回的引用赋给b2变量。
现在,您只能通过b2“看到”Base的成员,即使实际的值在执行时引用了Child的一个实例。但是任何在Child中被覆盖的来自Base的方法在被调用时都将使用被覆盖的版本...所以当你调用
b2.subtract();JVM找出b2引用的对象的实际类型,并使用该类的subtract实现-在本例中,是打印"Child Subtract“的方法。
编辑:你特别问过你可以在哪里使用这种东西,以及它是如何帮助你的…
您可以在任何时候声明一个更通用类型的变量(超类或接口),但又为它赋值,而这个值恰好是接口的子类或实现。再举一个例子:
List<String> strings = new ArrayList<String>();以通用方式声明变量的主要优点是保留了灵活性-以后可以从使用ArrayList<T>改为使用List<T>的其他实现,并且代码应该仍然有效。您基本上是在说,“我只需要List<T>提供的成员和保证--我使用ArrayList<T>的事实有点偶然。”
一个类似的例子是决定一个方法应该返回什么类型-通常你只想声明你返回了一个通用类型(或接口),即使实现知道它返回的是哪个具体类型。这隐藏了实现细节,这允许您稍后更改它们。
发布于 2010-12-15 16:16:26
Base b2 = new Child(); 子对象可以使用Super的Reference。
对于b2.method();
在编译时,BaseClass中必须有method();。
在运行时,对象的方法将被调用,因此这里的对象是来自Base b2 = new Child();的子级
所以孩子的method()版本将会被执行。
使用:
多态性在设计企业级系统时非常有用,因为您可以创建和定义多个接口层,这些接口层允许外部方或外部软件以特定方式与您的系统交互。我们都知道发布API对系统集成有多大帮助,但如果内部系统需要更改,则API可能需要重新发布,集成的系统可能需要重新工作。为了避免这种情况,在设计过程中应该仔细考虑对象API以及整个系统API。要确保健壮的系统能够处理具有比最初预期更复杂的方法的对象,一种方法是使对象API是多态的。通过这种方式,系统知道正在传递给它的对象的“面”,但不必知道即席变化。
还请参阅
https://stackoverflow.com/questions/4447924
复制相似问题