Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在php中设计参数类型变化的继承?_Php_Design Patterns_Inheritance_Types_Hints - Fatal编程技术网

如何在php中设计参数类型变化的继承?

如何在php中设计参数类型变化的继承?,php,design-patterns,inheritance,types,hints,Php,Design Patterns,Inheritance,Types,Hints,其想法是创建一个类似DOM的树。但是有一些限制,只有某些类型才能真正包含其他类型 我想使用接口|抽象类|超类来实现一些众所周知的js函数,如appendChild、replaceChild等 我使用的是page、block和item类,其中页面可以包含块,块可以包含块或项 示例:页面是网页,块可以是列表元素,项可以是列表项元素 但是这些对象包含的不仅仅是html数据,概念也不仅仅是简单的html表示。这是管理项目的总体思路,无论它们是实际的表示还是仅仅是抽象的对象。这个概念本身适用于许多不同的层

其想法是创建一个类似DOM的树。但是有一些限制,只有某些类型才能真正包含其他类型

我想使用接口|抽象类|超类来实现一些众所周知的js函数,如appendChild、replaceChild等

我使用的是page、block和item类,其中页面可以包含块,块可以包含块或项

示例:页面是网页,块可以是列表元素,项可以是列表项元素

但是这些对象包含的不仅仅是html数据,概念也不仅仅是简单的html表示。这是管理项目的总体思路,无论它们是实际的表示还是仅仅是抽象的对象。这个概念本身适用于许多不同的层次结构

我想要实现的是尽可能多地重用父类的代码,添加子类对于所有类基本上都是相同的,但是不同的类型提示与允许作为子类添加的类型相匹配

基本上有四种方式让我了解自己:

我使用一个接口,它允许我向超类键入提示,但不允许更改这些提示。 我使用一个带有公共方法的超类,因此我可以重新定义类型提示,这完全违背了继承前提条件时的常规做法。 我使用了一个带有保护方法的超类,这似乎仍然很奇怪。 我去掉了任何超类,只定义了几次几乎相同的类。 我使用一种方法来检查类型,尽管有类型提示的特性。 所以,如果有人仍然愿意回答,我很乐意接受任何建议、想法或暗示,选择哪一个选项。我希望我能很好地描述这个问题

如果我错过了什么,我很感激听到它

代码

超类方式有效,但打破了继承实践的前提条件

class Base {

    public|protected function appendChild(Base $child) {
        // do stuff
    }
}

class Block extends Base {

   public function appendChild(Block $child) {
       parent::appendChild($child);
   }

}
接口方式不起作用。它决不能这样做

interface Interface1 {

    public function appendChild(Base $child);

}

class Base implements Interface1 {

    public|protected function appendChild(Base $child) {
        // do stuff
    }
}

class Block extends Base{

   public function appendChild(Block $child) {
       parent::appendChild($child);
   }

}

编辑的部分是粗体的

界面对我来说最有意义。一个类可以扮演多个角色,因为它可以实现多个接口

// you don't need any methods in the interfaces
class Foo implements Inline, Block {} 
将与以下两方面合作:

appendChild(Inline $foo); and appendChild(Block $foo);
接口可以相互扩展,因此可以为所有对象提供公共接口

您仍然可以使用继承来重用实现,并且可以灵活地严格使用InHirtance树来重用实现,而不受页面逻辑的限制,您永远不会被迫使用StaticSimpleton扩展HeavyDatabaseyWidget

如果没有接口,我会选择选项5:只需让appendChild调用$child->canBeChildOf$this和/或$this->accepts$child。同样,逻辑和实现是独立的,您可以自由地使用逻辑


PHP在运行tmie时会进行类型检查,所以使用类型系统不会给您带来太多好处。

您不能扩展吗?谢谢您的评论。我并不是真的想复制DOM树,有比我能想到的任何解决方案都好的方法,但我需要类似的行为。上面的例子只是,一个澄清其背后思想的例子。我纠正了这个问题,指出我并没有试图重建DOM扩展。好吧,也许已经太晚了,但我不明白。如果使用接口,则无法重新声明任何前提条件或类型提示。因此,我需要坚持在接口any、superclass、any中指示的类型提示。在这方面,多个接口如何帮助我?在问题中添加了一些代码,希望更容易看到。我知道,可捕获的致命错误;非常感谢你的快速回答,我只是想听听其他人的意见,如果没有$this->accepts或类似的东西,它是不会工作的。明天早上我会把你的答案标记为正确答案,也许有人有一个绝妙的想法来解决这个问题;