简体   繁体   English

如何在PHP中通过更改参数类型来设计继承?

[英]How to design an inheritance with changing parameter types in php?

The idea is to create a DOM-like tree. 这个想法是创建一个类似DOM的树。 But there are some restrictions, that only certain types can actually contain the other. 但是有一些限制,只有某些类型可以实际包含其他类型。

I want to use an interface|abstract class|superclass to implement some well known js-functions as appendChild, replaceChild etc. 我想使用接口|抽象类|超类来实现一些众所周知的js函数,例如appendChild,replaceChild等。

I'm using the classes page, block and item, where pages can contain blocks and blocks can contain either blocks or items. 我正在使用类页面,块和项目,其中页面可以包含块,而块可以包含块或项目。

Example: Page is a web page, block could be an list element and item could be an list item element. 示例:页面是网页,块可以是列表元素,项目可以是列表项目元素。

But these objects contain more than just html-data and the concepts goes beyond just plain HTML representation. 但是这些对象不仅仅包含html数据,而且这些概念还超出了普通HTML表示的范围。 It's an overall idea of managing items, wether they have an actual representation or are just abstract objects. 这是管理项目的总体思路,无论它们具有实际的表示形式还是仅仅是抽象的对象。 The concept itself works for many different hierarchies. 该概念本身适用于许多不同的层次结构。

What I want to achieve is to reuse as much code of the parent class as possible (adding a child is basically the same for all classes) but to differ the type hints to match the allowed types to add as a child. 我想要实现的是尽可能多地重用父类的代码(添加子代对于所有类基本上是相同的),但是要使类型提示与允许添加为子代的类型相匹配。

There are basically four ways I found out myself: 我发现自己的方法基本上有四种:

  1. I use an interface, which allows me to type hint to the superclass but not to change these. 我使用一个接口,该接口允许我向超类键入提示,但不能更改它们。
  2. I use a superclass with public methods, so i can redefine the type hints (which is totally against usual practices when heriting preconditions). 我将超类与公共方法一起使用,因此可以重新定义类型提示(在继承先决条件时,这完全违反了常规做法)。
  3. I use a superclass with protected methods, which seems still being quite quirky. 我使用带有受保护方法的超类,这似乎仍然很古怪。
  4. I get rid of any superclass and just define almost the same class several times. 我摆脱了任何超类,只是多次定义几乎相同的类。
  5. I use a method to check for the type, despite the feature of type hints. 尽管有类型提示功能,但我还是使用一种方法来检查类型。

So, if anyone is still willing to answer I'm happy for any proposition, idea or hint, which option to choose. 因此,如果有人仍然愿意回答,那么我对任何主张,想法或暗示(选择哪个选项)都很满意。 I hope I could describe the issue well enough. 我希望我能很好地描述这个问题。

And if there is something i missed I'm thankful to hear it ;) 如果有什么我想念的,我很感激;)

Code

Superclass way (works, but breaks precondition inheriting practice) 超类方式(有效,但打破了前提继承实践)

class Base {

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

class Block extends Base {

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

}

Interface way (Does not work. It must not) 接口方式(不起作用。一定不能)

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);
   }

}

Edited parts are bold 编辑的部分以粗体显示

Interface makes most sense to me. 界面对我来说最有意义。 You can have one class that plays multiple roles, as it can implement multiple interfaces. 一个类可以扮演多个角色,因为它可以实现多个接口。

// you don't need any methods in the interfaces
class Foo implements Inline, Block {} 

will work with both: 可以同时使用:

appendChild(Inline $foo); and appendChild(Block $foo);

and interfaces can extend each other, so there can be common interface for all your objects. 和接口可以互相扩展,因此所有对象都可以有一个通用接口。

You can still use inheritance to reuse implementation, and you'll have flexibility to use inhertiance tree strictly for reuse of implementation, not limited by your page logic (you'll never be forced to make StaticSimpleton extend HeavyDatabaseyWidget ). 您仍然可以使用继承来重用实现,并且可以灵活地严格使用继承树来重用实现,而不受页面逻辑的限制(您永远不会被迫让StaticSimpleton扩展HeavyDatabaseyWidget )。

If not interfaces, I'd go for option 5: just make appendChild call $child->canBeChildOf($this) and/or $this->accepts($child) . 如果没有接口,我将选择选项5:只需使appendChild调用$child->canBeChildOf($this)和/或$this->accepts($child) Again, logic and implementation will be independent, and you'll have a lot of freedom with your logic. 同样,逻辑和实现将是独立的,并且您的逻辑将有很多自由。

PHP does type checks at run tmie, so use of type system doesn't buy you much anyway. PHP在运行tmie时会进行类型检查,因此使用类型系统并不会给您带来多少好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM