从链接类继承

时间:2011-06-01 21:33:43

标签: oop

这个问题是关于任何静态类型语言的OOP。假设我有两个类,其实例保持彼此的指针/引用。在我的例子中,一个类是一个容器,另一个类是一个包含对象的包装器,它包含一个指向它所在容器的指针。

class Container {
  Element[] elements;
}
class Element {
  // ... data...
  Container holds_me;
}

Container的构造函数创建一个Element对象来包装每个包含的对象,并将它们的holds_me指针设置为自己。

现在我想继承这些类。我想要一个DerivedContainer类,它继承自Container并包含DerivedElement个对象,其中DerivedElement继承自Element并引用包含DerivedContainer的对象宾语。这样做的正确方法是什么(或者做错了什么)?

最直接的事情是DerivedContainer的构造函数创建DerivedElement并将它们存储在elements中,并将它们的holds_me指针设置为自身。然后,ContainerElement的所有方法都可以使用,但DerivedContainerDerivedElement中定义的任何新方法都必须向下转换elements中保存的对象和holds_me以便在它们上调用未在基类中定义的任何新方法。这看起来不太漂亮;所以我想知道,有更好的解决方案吗?

3 个答案:

答案 0 :(得分:1)

是的,这是正确的方式,没有任何更多的信息,恕我直言。如果您认为Element中的所有方法都可以应用于每个元素,那么这是有意义的,但是应该知道任何有关Derived功能集的类是(理想情况下)DerivedElement和(如果需要的话) )DerivedContainer。换句话说,对于其他任何人来说,元素和容器只是 元素和容器。

您有时可以使用模板(C ++)或泛型(Java)做得更好,因为这些功能背后的想法是Container<Element>知道它包含元素而Container<DerivedElement>知道它持有DerivedElements,但是如果你有一个异构的Container,你真的必须让每个子类通过尝试向下转换来处理派生的功能。

答案 1 :(得分:1)

如果您的语言支持,您可以使用泛型/模板。 Container类可以将Elements类作为参数化类型。这样,你就可以忘记向下传播元素。

答案 2 :(得分:0)

如果有人感兴趣,我已经意识到可以使用抽象类型在这里做更多或更少的事情。这是一些Scala代码:

abstract class Container { ctnr =>
  type E <: Element
  class Element { this : E =>
    // data
    def holds_me = ctnr
  }
  var elements : Array[E]
}

原始容器是一个抽象类,包含嵌套的元素类和抽象类型的元素。子类型断言E <: Element要求E始终是Element的子类,而自引用this : E =>强制Element的任何实例化属于该类型{ {1}}(由E的某些实现实例化。)

Container