I didn't quite rule out AbstractBird, but I did put what
is in hindsight a silly restriction on it. So my module
is pretty close to what you would want.
As I mentioned in the documentation,
an abstract class that inherits from an abstract class will
bypass the checks that abstract classes get. Why? Because
when it uses the classes further up, they do not trigger
their own check, and when someone calls it, it blocks its
own check and does not rethrow to the classes that would
have implemented the check.
However I required abstract classes to implement at least
one abstract method because I didn't think it was worthwhile
to not do so. But you have given a good reason. I am
about to update the name to AbstractClass. When I have
done that your example would look like this. First your
abstract base class:
package SwimmingFlyingThing;
use AbstractClass qw(swim fly);
Now your abstract class that inherits:
pacakage AbstractBird;
use SwimmingFlyingThing;
use AbstractClass;
@ISA = 'SimmingFlyingThing';
sub fly { print "Flap Flap Flap" }
And then finally a real class:
package Duck;
@ISA = 'AbstractBird';
sub swim { print "Paddle paddle paddle" }
sub new { ... }
And yes, Class::Contract does indeed implement a
similar idea, but is a far bigger change to Perl's
inheritance mechanisms.
I am toying with the idea of making abstract classes
unable to bless. With my module it would be trivial to
do so. Just override bless in derived modules. This
time I will be the one to write to Damian to get his opinion... :-) |