使用超类而不是子类初始化对象

时间:2014-06-20 14:11:29

标签: object inheritance declaration

我最近看到了这个示例代码,但我并不知道如何能够轻松找到这个问题的答案。在代码中,Dog对象,Cow对象和Snake对象都被声明为Animal对象。那么使用更通用的类声明对象是否有效?例如,我可以将任何对象声明为Object(因为所有类都是对象类的子类)?声明特定或更一般的优点/缺点是什么?这是为了便于阅读吗?

class Animal {
  void whoAmI() {
    System.out.println("I am a generic Animal.");
  }
}
class Dog extends Animal {
  void whoAmI() {
    System.out.println("I am a Dog.");
  }
}
class Cow extends Animal {
  void whoAmI() {
    System.out.println("I am a Cow.");
  }
}
class Snake extends Animal {
  void whoAmI() {
    System.out.println("I am a Snake.");
  }
}

class RuntimePolymorphismDemo {

  public static void main(String[] args) {
    Animal ref1 = new Animal();
    Animal ref2 = new Dog();
    Animal ref3 = new Cow();
    Animal ref4 = new Snake();
    ref1.whoAmI();
    ref2.whoAmI();
    ref3.whoAmI();
    ref4.whoAmI();
  }
}
The output is

I am a generic Animal.
I am a Dog.
I am a Cow.
I am a Snake.

1 个答案:

答案 0 :(得分:0)

您可以使用对象实例化每个其他类,但不能使用基元实例化,但即使它们具有使它们成为类的包装器。

这不是一个好的面向对象的实践,因为你希望程序尽可能地安全。

在这些课程中加入更多不同的方法,那就是当你开始看到问题时。

让我们说Dog也有方法chewButt()。

Animal dog = new Dog();
dog.chewButt();

没问题。但这并不是你所允许做的全部。

Animal dog = new Cow();

编译......

dog.chewButt();

现在我们遇到了问题。牛无法达到它的屁股。

在宣布超级课程时,您希望尽可能严格,但要足够宽松,以便快速完成工作。你可能想要宽松的原因是这样的。

狗和蛇有点太不同了。我正在创建一个从Animal扩展的新子类Mammal。我把狗和牛以及其他任何东西放进去。

现在我可以放心,我可以做到:

Mammal mouse = new Mouse();
mouse.suckleYoung();
cat.suckleYoung();
whale.suckleYoung();

但如果我不小心尝试:

Mammal snake = new Snake();

我希望编译器在我深入编码之前就抱怨。

我希望有所帮助。经验肯定会很快将这些点燃烧到你的大脑中。

编辑:引用评论:我仍然没有得到什么原因,我不会总是只声明我的狗对象像“狗狗=新狗();”与示例代码“Animal dog = new Dog();

”中的对比

这是因为你的狗的功能也确保与所有动物(狗,猫,蜥蜴)一起工作。如果你选择其他路线,你将不得不为每类动物编写一个单独的功能。更糟糕的是,您所做的每个功能都具有相同的代码。而是在Animal中编写一次方法,每个扩展类都有这组方法。想象一下,你已经意识到你所写的方法有些错误,你必须改变一行,但你必须在每个动物的模块中进行,因为你没有花时间创建一个Animal超类。