你能在继承树中重新创建一个方法摘要吗?

时间:2014-07-04 13:36:37

标签: java inheritance abstract-class multiple-inheritance abstract

编辑:

要明确:设计非常丑陋并不重要。关键是,设计就在那里,我必须添加另一个FlyingMotorizedVehicle子类,如果我忘记添加foo(...),它将无法按预期工作。所以我只是想知道我是否可以将其重新定义为抽象。


我现在面对一个非常奇怪的继承情况。 可以说,我有三个课程,VehicleMotorizedVehicleFlyingMotorizedVehicle以及一些课程AirplaneHelicopter,...:

public abstract class Vehicle {

    abstract Something doStuff(...);

    abstract SomethingElse doOtherStuff(...);

    abstract Foo bar(...);

}

public class MotorizedVehicle extends Vehicle {

    @Override
    Something doStuff(...) {
        return new Something();
    }

    @Override
    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    }

    @Override
    Foo bar(...) {
        return new Foo();
    }

}

public class FlyingMotorizedVehicle extends MotorizedVehicle {

    @Override
    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    }

}

public class Airplane extends FlyingMotorizedVehicle  {

    @Override
    Foo bar(...) {
        //do something different
        return new Foo();
    }

}

public class Helicopter extends FlyingMotorizedVehicle {

    @Override
    Foo bar(...) {
        //do something totally different
        return new Foo();
    }

}
[...]

所以Vehicle是一个提供一些抽象方法的抽象类。 MotorizedVehicleVehicle的子类,具有其方法的具体实现。 FlyingMotorizedVehicle再次是MotorizedVehicle的子类,它覆盖了MotorizedVehicle方法子集的实现。

现在有子类HelicopterAirplane以及可能的其他一些例子覆盖了MotorizedVehicle#bar(...)的具体实现。 我想要的是“强制”MotorizedVehicle的每个子类必须覆盖bar(...)方法并提供自己的实现。

是否可以通过以下方式更改FlyingMotorizedVehicle

public class FlyingMotorizedVehicle extends MotorizedVehicle {

    @Override
    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    }

    abstract Foo bar(...);

}

所以我只是将bar(...)重新定义为抽象方法?我的IDE并没有抱怨它,但这当然并不意味着它实际上会起作用。

我希望你能得到我在这里指出的内容。

提前致谢

Bluddy

4 个答案:

答案 0 :(得分:2)

是的,您必须将bar(...)重新定义为抽象方法。 然后你必须将public class FlyingMotorizedVehicle声明为抽象类

public abstract class FlyingMotorizedVehicle extends MotorizedVehicle {

    @Override
    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    }

    abstract Foo bar(...);

}

答案 1 :(得分:1)

您希望MotorizedVehicle的子项的默认实现为bar,但FlyingMotorizedVehicle的子项不是这样。

abstract class BasicMotorizedVehicle
    // no bar
    ... // Rest of old MotorizedVehicle

class MotorizedVehicle extends BasicMotorizedVehicle
    Foo bar(...) { ... }

class FlyingMotorizedVehicle extends BasicMotorizedVehicle

答案 2 :(得分:0)

兄弟,也可以学习 接口

如果您希望某些类(例如Vehicle)仅提供函数原型,则应始终使用接口

将你的FlyingMotorizedVehicle作为抽象类。

  • 抽象类可以有两种类型的函数,只有原型(抽象函数)或完全实现的函数。
  • 接口只有函数原型,它们不能包含函数实现,需要实现接口。

有待进一步研究,您可以找到许多有用的链接,包括this one.

============================= CODE-例=============== ========================

适用于车辆

public interface Vehicle {

    Something doStuff(...);   
    SomethingElse doOtherStuff(...);
    Foo bar(...);

}

适用于FlyingMotorizedVehicle

public abstract class FlyingMotorizedVehicle extends MotorizedVehicle {

    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    } 
}

=============================================== ================================

快乐 OOP-ing

答案 3 :(得分:0)

可以。实际上,它甚至说您可以显式in the language spec

  

非抽象的实例方法可以被抽象方法覆盖。

您将面对的问题在以下几段中进行了描述:

  

抽象方法的声明必须直接出现在抽象类(称为A)中,除非它出现在枚举声明中(第8.9节);否则会发生编译时错误。

所以,问题是您的类不是抽象的,就像其他人已经指出的那样;了解规范中描述它的特定部分可能会很有用。