Can you re-make a method abstract in the inheritan

2019-03-06 14:22发布

问题:

EDIT:

To be clear: The fact that the design is quite ugly is not the point. The point is, that the design is there and I am in the situation to have to add another sub-class of FlyingMotorizedVehicle which would not work as expected if I forgot to add the foo(...). So I just was wondering if I could redefine it as abstract.


I am right now facing a quite weird inheritance situation. Lets say, I have three classes, Vehicle, MotorizedVehicle and FlyingMotorizedVehicle as well as a bunch of classes Airplane, Helicopter, ...:

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();
    }

}
[...]

So Vehicle is an abstract class providing some abstract methods. MotorizedVehicle is a sub-class of Vehicle with concrete implementations of its methods. FlyingMotorizedVehicle again is a sub-class of MotorizedVehicle overriding the implementations of a subset of MotorizedVehicles methods.

Now there are the sub-classes Helicopter, Airplane and potentially some others which in the example override the concrete implemenatation of MotorizedVehicle#bar(...). What I want is to "force" every sub-class of MotorizedVehicle to have to override the bar(...) method and provide its own implementation.

Is it possible to just change the FlyingMotorizedVehicle in the following way:

public class FlyingMotorizedVehicle extends MotorizedVehicle {

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

    abstract Foo bar(...);

}

So that I just redefine the bar(...) as abstract method? My IDE is not complaining about it, but that of course does not mean, that it will actually work.

I hope you get what I try to point out here.

Thanks in advance

Bluddy

回答1:

Yes, You have to redefine the bar(...) as abstract method. Then you have to declare public class FlyingMotorizedVehicle as a abstract class as well

public abstract class FlyingMotorizedVehicle extends MotorizedVehicle {

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

    abstract Foo bar(...);

}


回答2:

You want children of MotorizedVehicle to have a default implementation of bar, but not so for the children of the FlyingMotorizedVehicle.

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

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

class FlyingMotorizedVehicle extends BasicMotorizedVehicle


回答3:

Brother, study Interfaces too.

If you want some class, such as Vehicle to only provide function prototypes, then you should always use Interface.

And make your FlyingMotorizedVehicle as abstract class.

  • Abstract class can have both types of functions, either prototype only (abstrac functions) or fully implemented functions.
  • Interfaces have only function prototypes, they can't contain function implementations, Interfaces are required to be implemented.

For further study, you can find many useful links, including this one.

=============================CODE-EXAMPLE=======================================

For Vehicle

public interface Vehicle {

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

}

For FlyingMotorizedVehicle

public abstract class FlyingMotorizedVehicle extends MotorizedVehicle {

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

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

Happy OOP-ing!



回答4:

Yes you can. In fact, it even says you can explicitly in the language spec:

An instance method that is not abstract can be overridden by an abstract method.

The problem you are facing is described a few paragraphs up:

The declaration of an abstract method mmust appear directly within an abstract class (call it A) unless it occurs within an enum declaration (§8.9); otherwise a compile-time error occurs.

So, the problem is that your class is not abstract, as others pointed out already; it may just be useful to know the specific parts of the spec which describe it.