1

我是java新手,所以这个问题似乎对某些人有一个明显的答案,但这给我带来了一些麻烦。

如果我有

ClassAClassB

ClassB extends ClassA

这段代码发生了什么?

public class ClassB extends ClassA{

    public void foo(){
        ClassA CA = new ClassB();

    }

}

从这里我可以ClassA通过CA<调用方法-这部分是有道理的..但我迷失了......

为什么我会这样做,重点是什么,实际发生了什么。

谢谢。

4

3 回答 3

1

我通过动物的例子学习了多态性。在实践中实际上并没有多大意义,但理解这些原则是很好的。

首先正确的方法:

class Animal {
   public void eat() {/* code for eating */};
   public void sleep() {/* code for sleeping */};
}

class Dog extends Animal {
   public void bark() { /* code for barking */ }
}

class Duck extends Animal {
   public void quack() { /* code for quacking */ }
}

使用此代码,您可以执行以下操作:

{
   Dog lassie = new Dog();
   Duck donald = new Duck();

   lassie.eat();
   lassie.sleep();
   lassie.bark();
   donald.eat();
   donald.sleep();
   donald.quack();

   List<Animal> barn = new ArrayList<Animal>();
   barn.Add(lassie);
   barn.Add(donald);
}

两者donaldlassie都可以eat()sleep(),因为它们都是Animals。他们每个人都发出自己的声音,他们可以塞在一起,因为他们都是Animals。

反例将如下代码:

class Dog {
   public void bark() { /* code for barking */ }
   public void eat() {/* code for eating */};
   public void sleep() {/* code for sleeping */};
}

class Duck {
   public void quack() { /* code for quacking */ }
   public void eat() {/* code for eating same as code in Dog */};
   public void sleep() {/* code for sleeping  same as code in Dog */};
}

现在您不能将它们都放在同一个容器中,因为它们是不同的类型。此外,您必须编写两次相同的代码(eating 和sleeping)。

于 2013-09-30T07:56:13.517 回答
1

当ClassA是一个没有实现某些功能的抽象类,而ClassB和其他一些ClassC是扩展 ClassA的具体类时,这种继承的另一种用法。

在这种情况下,ClassA 实现了 ClassB 和 ClassC 的共同行为,并且这两个类添加了它们所需的功能。

让我们添加一个例子: ClassA是一个Car,它可以驱动、转弯和停止。所有这些动作都在 Car 中实现,但它是一个抽象的汽车。

ClassB是一个SportsCar,它增加了“Race”的功能。

ClassC蝙蝠车,它增加了“从头灯发射火箭”的功能。

所以,在这个例子中,你只实现了一次驱动、转向和停止,并在继承类中添加了其他功能。

于 2013-09-30T08:19:10.800 回答
1

为什么我会这样做,重点是什么

您想要这样做的通常情况是创建对象的代码和使用该对象的代码不在同一个方法/类/模块中,但需要稍微解耦。

使用多态/继承,您可以为类的用户定义一个接口(ClassA在您的情况下),并且能够在不同的实现(例如ClassB在您的情况下)之间切换,而无需调用代码知道这一点。

一个典型的例子是使用集合做某事的方法。Collection 是一个接口,有很多不同的实现。调用代码可以对 Collection 执行某些操作(例如迭代元素),而无需知道它是 ArrayList 还是 HashSet。

以及实际发生的事情。

发生的情况是运行时系统似乎您正在调用方法的对象实例是 的实例ClassB,并且它将代码分派到正确的位置。这是在调用代码不需要知道的情况下完成的。对于调用者来说,重要的是它想要拥有的接口中定义的所有方法 ( ClassA) 都已实现(Java 编译器会确保这一点)。

于 2013-09-30T07:36:06.017 回答