Oop 从链接类继承
这个问题是关于任何静态类型语言中的OOP。假设我有两个类,它们的实例维护指向彼此的指针/引用。在我的例子中,一个类是容器,另一个类是包含对象的包装器,它维护指向它所在容器的指针Oop 从链接类继承,oop,Oop,这个问题是关于任何静态类型语言中的OOP。假设我有两个类,它们的实例维护指向彼此的指针/引用。在我的例子中,一个类是容器,另一个类是包含对象的包装器,它维护指向它所在容器的指针 class Container { Element[] elements; } class Element { // ... data... Container holds_me; } Container的构造函数创建一个元素对象来包装每个包含的对象,并设置它们的保存指向自身的指针 现在我想从这些类继承。我
class Container {
Element[] elements;
}
class Element {
// ... data...
Container holds_me;
}
Container
的构造函数创建一个元素
对象来包装每个包含的对象,并设置它们的保存指向自身的指针
现在我想从这些类继承。我想要一个DerivedContainer
类,它继承自Container
并包含DerivedElement
对象,其中DerivedElement
继承自Element
并引用包含的DerivedContainer
对象。做这件事的正确方法是什么(还是做错事)
最简单的事情是DerivedContainer
的构造函数创建DerivedElement
s并将它们存储在元素中,并将它们的指针指向自身。然后容器
和元素
的所有方法都会起作用,但是在DerivedContainer
和DerivedElement
中定义的任何新方法都必须向下转换elements
和holds\u me
中包含的对象,以便调用基类中未定义的任何新方法。这看起来并不漂亮;所以我想知道,有没有更好的解决方案?是的,这是正确的方法,没有更多的信息,IMHO。如果您认为元素中的所有方法都可以应用于每个元素,那么这是有意义的,但是应该了解派生功能集的唯一类是(理想情况下)DerivedElement和(如果需要)DerivedContainer。换句话说,对于其他人来说,元素和容器只是元素和容器
有时使用模板(C++)或泛型(Java)可以做得更好一些,因为这些特性背后的思想是容器
知道它包含元素,容器
知道它包含派生元素,但是如果您有一个异构容器,您必须让每个子类通过尝试向下转换来处理派生功能。如果您的语言支持它,您可以使用泛型/模板。容器类可以将Elements类作为参数化类型。这样,您就可以忘记向下转换元素了。如果有人感兴趣,我已经意识到可以使用抽象类型或多或少地实现我最初想要的功能。下面是一些Scala代码:
abstract class Container { ctnr =>
type E <: Element
class Element { this : E =>
// data
def holds_me = ctnr
}
var elements : Array[E]
}
只是一个建议--您使用的双链接连接可能最终会出现问题。如果您的容器类有一个静态查找方法“findContainerWith(object)”,它可能会降低您以后遇到的一些复杂性。此外,当您添加需求时,该方法也可以重新实现(例如,您需要两个容器包含相同的对象或类似讨厌的东西的情况)。但是,Container
不会是Container
的子类,是吗?是的,但这真的是必要的吗?在最初的设计中,容器始终是一个容器,不管它里面装的是什么。它包含的元素可以形成类层次结构,也可以不形成,泛型设计仍然如此。我不明白为什么您希望Container成为Container的子类。是因为利斯科夫原理吗?(一个容器必须是一个容器,因此它必须是一个子类)从我的示例中可能不清楚。我并不打算容器成为通用容器对象;在我预期的应用程序中,它是一种更具体的东西,碰巧也包含一组元素,DerivedContainer以不同的方式扩展了Container的功能,而不仅仅是包含不同种类的元素。如果Container是一种更“定制”的容器,在我看来,你最初的解决方案并没有那么糟糕:博凯,谢谢。我希望派生类能够以某种方式静态地确保它们的引用只指向其他派生类。
class ContainerImpl extends Container {
type E = Element
// initialize 'elements' using 'new Element()'
}
abstract class DerivedContainer extends Container {
override type E <: DerivedElement
class DerivedElement extends Element { this : E =>
// more data
}
}
class DerivedContainerImpl extends DerivedContainer {
type E = DerivedElement
// initialize 'elements' using 'new DerivedElement()'
}