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

发布于 2024-08-19 16:55:39 字数 1428 浏览 2 评论 0原文

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

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

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

示例:Page 是网页,block 可以是列表元素,item 可以是列表项元素。

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

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

我自己发现的基本上有四种方法:

  1. 我使用一个接口,它允许我向超类输入提示,但不能更改它们。
  2. 我使用带有公共方法的超类,因此我可以重新定义类型提示(这完全违反继承先决条件时的通常做法)。
  3. 我使用带有受保护方法的超类,这似乎仍然很奇怪。
  4. 我摆脱了任何超类,只是多次定义几乎相同的类。
  5. 尽管有类型提示的功能,我还是使用一种方法来检查类型。

所以,如果有人仍然愿意回答,我很高兴有任何提议、想法或提示,以及选择哪个选项。我希望我能很好地描述这个问题。

如果我错过了一些东西,我很高兴听到它;)

代码

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

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

}

编辑部分加粗

The idea is to create a DOM-like tree. 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.

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. 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

预谋 2024-08-26 16:55:39

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

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

可以与两者一起使用:

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

并且接口可以相互扩展,因此所有对象都可以有通用的接口。

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

如果不是接口,我会选择选项 5:只需让 appendChild 调用 $child->canBeChildOf($this) 和/或 $this-> ;接受($child)。同样,逻辑和实现将是独立的,并且您的逻辑将有很大的自由度。

PHP 在 run tmie 时进行类型检查,因此使用类型系统无论如何不会给您带来太多好处。

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).

If not interfaces, I'd go for option 5: just make appendChild call $child->canBeChildOf($this) and/or $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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文