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