【问题标题】:VB.NET inheritance - do all properties in the derived classes have to be declared in the base class?VB.NET 继承 - 派生类中的所有属性都必须在基类中声明吗?
【发布时间】:2011-08-08 18:08:49
【问题描述】:

我正在重构,但遇到了障碍。

背景:

我有一个基类和几个继承的派生类。派生类并不总是需要具有相同的属性。如果派生类之间共享任何属性,则这些属性将存在于基类级别(例如,“Contents”)。

同样,下面的 GoodDocument 有“GoodThings”,但不希望/不需要有“BadThings”。

我想将 'GoodDocument' 和 'BadDocument' 的实例都视为类型 'Document'

public mustinherit class Document
  public property Contents as string
  public sub new()...
end class 

public class GoodDocument
  inherits Document
  public property GoodThings as string
  public sub new()...
end class

public class BadDocument
  inherits Document
  public property BadThings as string
  public sub new()...
end class

DocumentWriter”类还将有几个派生类:(“GoodDocumentWriter”和“BadDocumentWriter”)。

我需要将 DocumentWriter.Doc 作为“文档”传递到代码中的许多其他位置。 Doc.GoodThings 只能从“GoodDocument”或“GoodDocumentWriter”的实例中调用。

public mustinherit class DocumentWriter
  public property Doc as Document
  public sub new()... 
end class

public class GoodDocumentWriter
  inherits DocumentWriter
  public sub new 
    mybase.Doc = new GoodDocument
  end sub
end class

public class BadDocumentWriter
  inherits DocumentWriter
  public sub new 
    mybase.Doc = new BadDocument
  end sub
end class

问题:

  • 是否存在允许派生类具有基类级别不存在的成员的设计模式?

  • 是否所有属性都必须位于基类级别?

修订

我试图简短地回答我最初的问题,但我犯了过度简化情况的错误。简而言之,我确实意识到应该可以在每个派生类上拥有不同的属性。 (我在半开玩笑的庄园里打了那个,并不想把它放在最后的帖子里)。

我现在意识到,我遇到的问题实际上是需要解决的更大问题的症状。

似乎我遇到了编译器投诉,可以通过进一步重构和更松散的耦合来纠正这些投诉。虽然其他人回答了我提出的基本问题,但 Ryan Gross 的例子确实帮助激发了一些新的想法。

谢谢!

【问题讨论】:

    标签: vb.net design-patterns inheritance


    【解决方案1】:

    在这种情况下,您应该做的是定义可以在接口中对Document 的实例执行的操作。在你的情况下,可能有一个 WriteThings 操作,所以你会有:

    public interface Writeable {
        public sub WriteThings();
    }
    

    然后在您的派生类中,您将实现该方法以利用该类的内部数据。例如:

    public mustinherit class Document implements Writeable
      public property Contents as string
      public sub new()...
      public sub WriteThings();
    end class 
    
    public class GoodDocument
      inherits Document
      public property GoodThings as string
      public sub new()...
      public sub WriteThings()
         //Do something with GoodThings
      end sub
    end class
    
    public class BadDocument
      inherits Document
      public property BadThings as string
      public sub WriteThings()
         //Do something with BadThings
      end sub
      public sub new()...
    end class
    

    最后,需要调用WriteThings的客户端代码通过一个接口访问它:

    public mustinherit class DocumentWriter
      public property Doc as Writable
      public sub new()... 
      public sub PerformWrite()
        Doc.WriteThings();
      end sub
    end class
    

    构建多个并行的类层次结构通常不是一个好主意。在这种情况下,一个DocumentWriter 类应该能够通过调用其WriteThings 方法来编写任何实现Writeable 的类。

    【讨论】:

    • 我不想疯狂地描述关于实际代码的太多细节(除非它有帮助),但想象一下 DocumentWriter 类必须(在基类级别)对 Document 之一做一些事情实例。基本上, DocumentWriter 类的代码不需要根据 Document 类型进行更改 - 它只需要将特定 Document 实例的 ref 传递给其他类。然后呢?
    • 我不知道为什么每个文档类型都需要一个单独的 DocumentWriter 子类
    • 在我的项目中,每个 Document 子类中都有大量不同的特定代码。我在 Document 基类中将这些方法设为“mustInherit”。我无法解决的问题是在尝试处理任一派生类之外的 Document 实例时。如果必须从 DocumentWriter 基类中删除并放入每个派生的编写器类中,则会复制/粘贴少量代码。导致这种情况的唯一原因是 Document 实例的类型。 (将 ByRef 文档作为文档传递)不起作用。
    • 谢谢瑞恩。我不确定这正是我最终会得到的结果,但您的示例帮助激发了一些新想法。
    【解决方案2】:

    如果所有属性都存在于基类级别,那么我不确定派生类的意义是什么。 :) 你可以用基类做所有事情。

    所以,是的。如果某些内容仅适用于 GoodDocument 而不适用于 Document,那么它应该在 GoodDocument 中。

    【讨论】:

      【解决方案3】:

      具体回答您的问题:

      • 是的,您只需在继承层次结构中创建多个层:您有一个基类,然后是许多两个“分支”(用您的术语来说,好和坏)。仅与任一分支相关的任何属性,您在从基类继承的类中声明。这些属性仅对该类和从它继承的任何类可见。

      • 不,可以在继承层次结构中的任何位置声明属性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-11
        • 1970-01-01
        相关资源
        最近更新 更多