为抽象类创建对象

时间:2014-09-19 13:06:48

标签: java oop abstract

我正在审核我的OOP,我对对象有一点疑问。好吧,我有一个超类Ship,它也是一个抽象类。 Ship有一些子类,即SubmarineDestroyer等等。

我知道我无法创建Ship类的对象,因为它是抽象的。但为什么以下仍然有效?

Ship s1 = new Submarine("ship 1");

6 个答案:

答案 0 :(得分:2)

行:Ship s1 = new Submarine("ship 1");

您不是创建抽象类Ship的对象,它仅仅是指向子类Submarine的对象的引用。你正在做的是创建子类的对象。

答案 1 :(得分:1)

这是由于多态性。

父类的引用可以保存子类对象。但是使用此引用可以调用在子类中正确覆盖的方法。

答案 2 :(得分:1)

您应该区分运行时类型和编译时类型。

假设您有以下声明:

Ship s1 = new Submarine("ship 1");
  • s1编译时类型是分配规则左侧的类型,例如编译时类型为Ship。您可以将s1分配给任何继承Ship

  • 的类型
  • s1运行时类型是赋值语句的右侧,例如运行时类型s1Ship具体实现(在您的情况下为Submarine)。

更多信息:

答案 3 :(得分:1)

简单来说,抽象类意味着您无法创建此类的新实例 但是,仍然可以将对象声明为Ship编译时类型 vs 运行时类型)以使用多态 ,允许你做一些有趣的事情,比如Ship数组,其中包含SubmarineDestroyer(还有更多)。

Ship[] army = new Ship[2];
army[0] = new Submarine("0");
army[1] = new Destroyer("1");

for( Ship s : army ) {
  s.fire();
}

在此示例中,我们可以在两个对象上调用fire(),因为fire()Ship的方法。由于船的攻击取决于船的类型(潜艇不会像驱逐舰一样射击),因此您将fire()方法设为Ship摘要并在Submarine和{{1}中实施}。

这些技巧在OOP中是必不可少的,并允许您实现强大的设计模式。如果您是初学者,请查看strategy patterntemplate method pattern,几年前他们改变了我对OOP的看法;)

希望这个小样本可以帮助你:)

答案 4 :(得分:0)

仅仅因为您无法实例化抽象类,并不意味着您无法拥有该类型的对象。您还可以拥有某个界面的对象,例如List<String> strings = new ArrayList<>()

您声明一个方法摘要,因为默认实现没有意义。

考虑一个名为shape的类,其中包含子类circlesquareshape有一个区域,但circle区域的计算方式与square的区域不同。

您可以在抽象getArea类中创建一个名为shape的抽象方法,让circlesquare提供它们的实现。

答案 5 :(得分:0)

s1是一艘船,您可以使用抽象类中定义的所有方法,但只能使用这些方法。 如果您的Submarine类中有其他方法(例如,dive,periscopeUp,...),则无法调用它们,因为它们未在您的抽象Ship类中定义。

使用它对于集合来说非常方便,例如,您现在可以在列表中存储不同类型的Ship。

List<Ship> ships = new ArrayList<Ship>();
ships.add(new Submarine("sub 1"));
ships.add(new Destroyer("des 1"));

如果您要定义“List<Submarine> subs”,则只能在该列表中存储潜艇类。