问题
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.
来源:https://stackoverflow.com/questions/24575618/can-you-re-make-a-method-abstract-in-the-inheritance-tree