【问题标题】:Parent class properities父类属性
【发布时间】:2016-07-18 14:34:48
【问题描述】:

如果我有一个父类或接口和 2 个从父类继承或实现接口的子类,并且我在父类中具有公共属性,但每个子类中都有一些不同的属性。我应该收集父类/接口中的所有属性还是将它们分开?

abstract class Customer
{
  string name { get; set; }
}

class GoldCustomer : Customer
{
  string Address { get; set;}
}

class SilverCustomer : Customer
{
  string Telephone { get; set;}
}

如果我将它们分开并从父级创建指向子级的引用,那么我无法访问分离的子级属性

Customer c = new GoldCustomer();
c.Address // error

哪种架构更正确且不违反任何设计模式?

abstract class Customer
{
  string name { get; set; }
  string Address { get; set;}
  string Telephone { get; set;}
}

class GoldCustomer : Customer
{

}

class SilverCustomer : Customer
{

}


Customer c = new GoldCustomer();
c.Address = "";

【问题讨论】:

  • 这取决于具体情况。以不需要违反 Liskov 替换原则的方式设计类 (en.wikipedia.org/wiki/Liskov_substitution_principle) 如果您觉得这很困难,请考虑组合而不是继承 (en.wikipedia.org/wiki/Composition_over_inheritance)
  • 这个问题太笼统了,正如 itsme86 所说,这取决于具体的情况。两种方法都可能是正确的,这实际上取决于您想要做什么。试着事先考虑一下你真正需要什么,这样你就不会产生不必要的依赖。

标签: c# inheritance interface polymorphism abstract-class


【解决方案1】:

我会稍微改变一下@itsme86 的方法,这样我就只有一个特定的ContactInfoAddressTelephone

public class Customer<T> where T : IContactInfo
{
    public string Name { get; }
    public T ContactInfo { get; }
}

public interface IContactInfo
{  }

public class GoldContactInfo : IContactInfo
{
    public string Address { get; }
}

public class SilverContactInfo : IContactInfo
{
    public string Telephone { get; }
}

public class GoldCustomer : Customer<GoldContactInfo>
{
     // Here does the GoldCustomer have a GoldContactInfo
}

public class SilverCustomer : Customer<SilverContactInfo>
{
     // Here does the SilverCustomer have a SilverContactInfo
}

【讨论】:

  • 好的,那么来电者如何询问客户的地址?您可能会求助于if (typeof(T) == typeof(GoldContactInfo) 之类的东西。除非你有别的把戏?它似乎对我来说太紧了。您不希望 Customer 类必须了解有关 ContactInfo 类型的任何信息。这就是构图的全部意义所在。
  • @itsme86 首先,我从未说过不需要T 类型。我只是改变了你的方法,因为就像你之前提到的问题很广泛,我想展示一些不同的方法。其次,我认为组合比“您不希望 Customer 类必须了解有关 ContactInfo 类的任何信息”具有更多的好处。请参阅这五个原因,例如javarevisited.blogspot.co.at/2013/06/…
【解决方案2】:

我可能不会使用继承,而是选择一组单独的类,其中包含客户类型的不同联系信息:

public class Customer
{
    public string Name { get; }
    public ContactInfo ContactInfo { get; }
    // Other common properties
}

public abstract class ContactInfo
{
    public virtual string Address => "";
    public virtual string Telephone => "";
}

public class GoldContactInfo : ContactInfo
{
    public override string Address { get; }
}

public class SilverContactInfo : ContactInfo
{
    public override string Telephone { get; }
}

【讨论】:

    【解决方案3】:

    在考虑继承和属性时,最简单的方法是用“is-a”和“has-a”来考虑它们。

    Customer 是否有 AddressTelephone 怎么样?如果一般的Customer 没有地址,那么下面的就没有意义了:

    Customer c = new GoldCustomer();
    c.Address = "";  // Customer does not have an Address property
    

    实际 对象确实 具有Address 属性的事实是无关紧要的。您已将其声明为 Customer 变量,因此编译器会这样对待它。

    如果所有客户都有地址和电话,那么还有哪些其他属性或行为使SilverCustomer 与“普通”客户不同?您可能还会发现Custmoer 表示级别的属性也更简单,但这取决于实际使用情况。

    【讨论】:

      猜你喜欢
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多