deadalnix wrote:
As all functionnality of a Ship are final, you basically ends
up with a mother ship that is a ship and then have some other
function that are de facto separated and unreachable from ship.
Yes, because Ship is designed to be the common denominator among
Ship types. This is not a problem, it's simply the far right side
of access-limitation. There's no need to abstract the type (as
you suggest below) simply because the base class went one
function "to tight".
Separation of concerns tells us that this should be 2 different
objects.
MotherShip is still concerned with being a Ship. It's intended as
a Ship, and should be classified as such. Removing the ability to
express this only forces coders into needlessly wrapping
functions:
class Ship { final void fire() {} }
class Bomber : Ship { void bomb() {} }
void main() {
auto b = new Bomber();
b.fire(); // can fire() like other Ships automatically
}
vs:
class Bomber {
Ship ship;
void fire() { ship.fire(); } // have to wrap this
}
This would be very annoying if you had many functions in the base
class and would probably lead the authors writing a single unused
virtual function into the base, just so they could derive types
from it.
As teha ddition of MotherShip to Ship are orthogonal, I would
argue that mothership functionality is better suited for its
own class/struct/whatever, and agregated with a ship.
A Ship wrapper is not conceptually a Ship. Nor could you cast a
Ship pointer to it. All you're doing by aggregating types is
complicating the structure for no-gain and loosing expression in
the process.