Могу ли я создавать Java-подобные интерфейсы в Perl?

Я понимаю, что модель Perl OO довольно примитивна; во многих отношениях это, по сути, взлом пространства имен.

Тем не менее, мне интересно, можно ли создать нечто вроде "интерфейса"? Моя цель состоит в том, чтобы иметь базовый класс, из которого продлены другие, основная цель которого состоит в том, чтобы сделать обязательными реализацию определенных методов (по имени прекрасно, без подписи) этими подклассами. Меня не волнует, является ли он "чисто виртуальным" классом (например, "интерфейс" в Java) или конкретным классом с фактическими реализациями для этих методов в суперклассе, но я хочу, чтобы он детерминистически требовал, чтобы подкласс реализует определенные методы суперкласса.

Возможно ли это? Если да, то как?

Ответ 1

Я думаю, что вся идея мандата на реализацию/перегрузку функций базового класса /subs не чуждо Perl. В какой момент вы бы представили механизм обеспечения соблюдения?

Если вы в порядке с этим во время выполнения, вы можете умереть, если вызвана реализация базового класса.

РЕДАКТИРОВАТЬ: На самом деле, да, класс:: Контракт - это путь.

Ответ 2

Вот ответ, используя Moose...

package Comparable;
use Moose::Role;

requires 'eq';

package Person;

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

Теперь атрибут size должен быть объектом, который реализует интерфейс "Comparable". В Moose-land интерфейсы являются ролями, а роли могут быть не просто определением интерфейса.

Ответ 3

Я не уверен, как вы сможете его реализовать. Однако посмотрите Moose, который является "Постмодернистской объектной системой для Perl 5".

Ответ 4

Class:: Contract может помочь в этом. Он поддерживает проверку времени компиляции.

Ответ 5

У меня есть легкий шаблон, который я называю "Compatible", и я обсуждаю его в своем ответе на Насколько важно указывать, реализует ли класс интерфейс в Perl?

Это просто вопрос вложения псевдопакетов в @ISA:

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

Вы нарушаете свой код, если не выполняете то, что ожидаете от X. На практике у меня есть куча документированных действий, которые я использую повторно, но класс, говорящий мне, что это X::Compatible, я использую, чтобы заверить себя, что он может делать то, что я ожидаю.

Так как perl 5.10 ввел концепцию DOES, которая примерно такая же легкая, объект X::Compatible наследуется от базового класса Object::Compatible, который реализует базу DOES, просматривая @ISA для /::Compatible$/ и отвечая утвердительно на что-либо там. Идея такова:

$object->DOES( $x ) == $object->isa( $x . '::Compatible' )

Ответ 6

Простое решение, которое создает ошибки во время выполнения:

package SomeVirtualClass;

use strict;
use warnings;

use Carp;

sub some_method { croak "virtual method some_method not overridden" }