VB.NET继承 - 必须在基类中声明派生类中的所有属性吗?

时间:2011-08-08 18:08:50

标签: vb.net design-patterns inheritance

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

背景

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

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

我想将“ GoodDocument ”和“ BadDocument ”的实例视为“文档”类型

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的例子确实帮助启动了一些新想法。

谢谢!

3 个答案:

答案 0 :(得分:3)

在这种情况下,您应该做的是定义可以在接口中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的任何类。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

具体回答你的问题:

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

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