问题
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 MotorizedVehicle
s 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