多重继承是很好的,只要你清楚地了解你的继承层次和一些潜在的陷阱(例如
perldoc perltoot中描述的那些),Perl就可以很好地处理它.然而,它没有讨论禁止使用具有多重继承的
fields pragma.实际上,我找不到任何关于此的文件……
这是一个例子:
package Parent1; use fields 'field1'; package Parent2; use fields 'field2'; package Child; use base qw(Parent1 Parent2);
这失败并出现错误:“无法在…处继承字段继承”
即使两个父母都有相同的字段,这也不起作用..即使他们可以证明是相同的,因为他们来自一个共同的祖父母:
package Grandparent; use fields qw(field1); package Parent1; use base 'Grandparent'; package Parent2; use base 'Grandparent'; package Child; use base qw(Parent1 Parent2);
正确实现这一点的一个缺陷是,子对象中字段的索引始终与其父对象中的索引相同.我不确定这个要求是否真的需要,但是……不像在C中,可以使用键入父类的指针来访问对象,Perl在对其引用进行操作时总是知道对象的实际类型(实际上fields pseudohash本质上是一个vtable,保存在每个对象实例上).特别是在上面的第二个例子中,从每个父节点继承的字段来自两个父节点,因此它们可以折叠在一起并且没有冲突的索引.
我确定还有其他问题,但我还没有找到它们.
任何对Perl内部有一定了解的人都可以对此发表评论吗?
解决方法
1)您可以尝试使用委托而不是继承,as described here.
2)此外,一些文档(包括上面的链接)似乎暗示多重继承的问题是由于伪聚类. Perl 5.10将“fields”pragma的实现更改为除pseudohashes之外的其他内容 – 如果它是一个选项,请尝试在Perl5.10中使用的方法并且它可能正常工作(我没有访问5.10因此无法实验,抱歉)
附:关于“我找不到任何关于此的文档…” – 至少在“官方”文档中提到这一点是来自Camel书(“Perl编程”,O’Reilly的Perl系列),第3版,章节31.3. “使用基地”:
“Multiple inheritance of field classes is not supported. The use base pragma raises an exception if more than one named base class has fields.”