Can I create Java-like interfaces in Perl?

2019-02-03 14:49发布

I understand that Perl's OO model is rather primitive; it is, in most respects, essentially a namespace hack.

Nevertheless, I wonder if it is possible to create something like an "interface?" My goal is to have a base class from which others are extended whose principal purpose is to make mandatory the implementation of certain methods (by name is fine, no signature necessary) by those subclasses. I don't really care if it's a "purely virtual" class (like an "interface" in Java) or a concrete class with actual implementational stubs for those methods in the superclass, but what I want is to make it deterministically necessary that the subclass implement certain methods of the superclass.

Is this possible? If so, how?

6条回答
甜甜的少女心
2楼-- · 2019-02-03 15:06

I am not sure how you will be able to implement it. However, have a look at Moose, which is "A postmodern object system for Perl 5".

查看更多
一夜七次
3楼-- · 2019-02-03 15:12

Simple solution that creates errors at runtime:

package SomeVirtualClass;

use strict;
use warnings;

use Carp;

sub some_method { croak "virtual method some_method not overridden" }
查看更多
Fickle 薄情
4楼-- · 2019-02-03 15:17

The Class::Contract can help with this. It supports compile-time contract checking.

查看更多
Rolldiameter
5楼-- · 2019-02-03 15:17

I have a lightweight pattern I call "Compatible", and I discuss it in my answer to How important is it to indicate if a class implements an interface in Perl?

It's just a matter of sticking pseudo packages in @ISA:

our @ISA = qw<... X::Compatible ...>;

You break their code if you don't do what they expect from X. In practice I have a bunch of documented behaviors that I reuse, but a class telling me it's X::Compatible is what I use to assure myself that it can do what I expect.

Since perl 5.10 has introduced the DOES concept, which is about as lightweight, a X::Compatible object inherits from a base class Object::Compatible which implements a base DOES by looking through @ISA for /::Compatible$/ and replying to the affirmative for anything in there. The idea is that:

$object->DOES( $x ) == $object->isa( $x . '::Compatible' )
查看更多
做自己的国王
6楼-- · 2019-02-03 15:19

Here's an answer using Moose ...

package Comparable;
use Moose::Role;

requires 'eq';

package Person;

has size => (
    is   => 'ro',
    does => 'Comparable',
);

Now the size attribute must be an object which implements the Comparable "interface". In Moose-land, interfaces are roles, and roles can be more than just an interface definition.

查看更多
祖国的老花朵
7楼-- · 2019-02-03 15:21

I think the whole idea of mandating implementation/overloading of base class's functions/subs is foreign to Perl. At which point would you envision the enforcement mechanism working?

If you're OK with doing this at runtime, you can die if your base class's implementation gets called.

EDIT: Actually, yes, Class::Contract seems to be the way to go.

查看更多
登录 后发表回答