使用接口来区分实现

时间:2013-11-20 19:27:11

标签: c# oop interface

以下是我的具体界面及其实现方案:

IPerson {string Name;}

American : IPerson {string Name;}
Asian : IPerson {string Name;}
European : IPerson {string Name;}

People = new List<IPerson>(); // This list can have American, Asian and/or European

当我访问People列表时,我需要区分美国,亚洲和欧洲,他们可以共享相同的界面。使用额外的接口(IAmerican,IAsian,IEuropean)是好的,它们都实现了IPerson并使用它来区分实现类,如:

IAmerican : IPerson {}
IAsian : IPerson {}
IEuropean : IPerson {}

American : IAmerican {string Name;}
Asian : IAsian {string Name;}
European : IEuropean {string Name;}

People = new List<IPerson>();
People.Add(new American());
People.Add(new Asian());
People.Add(new European());

var americans = People.OfType<IAmerican>(); // Getting all Americans from People

新界面不是很有用,而是要隔离对象。这是一个好方法还是应该在IPerson中实现某些类型属性来区分其实现?

6 个答案:

答案 0 :(得分:5)

你不需要做第二步,你的第一步也应该工作。

void Main()
{
    var people = new List<IPerson>();
    people.Add(new American { Name = "jack"});
    people.Add(new American { Name = "John"});
    people.Add(new Asian { Name = "ho"});

    Console.WriteLine (people.OfType<American>());

}

public interface IPerson {
    string Name {get; set;}
}

class American : IPerson {public string Name {get; set; }}
class Asian : IPerson {public string Name {get; set; }}
class European : IPerson {public string Name {get; set; }}

输出:

  

插孔
  约翰

该列表将每个对象定义为它们的公分母(IPerson),但这并不意味着它会丢失对实际对象的跟踪。我认为不需要创建过时的接口。

话虽如此:我更喜欢这里的作品而不是继承。 AmericanEuropean的区别是什么?在Person类中保留一个属性(使其成为一个类而不是一个接口),指示一个人的区域性。

答案 1 :(得分:2)

类型不仅是可用的鉴别器。您可以直接询问对象:

enum Continent { Europe, Asia, America }

public interface IPerson 
{  
    string Name { get; set; }
    Continent Continent { get; set; }
}

public class Asian : IPerson
{
    public Continent Continent
    {
        get 
        {
           return Continent.Asia;
        }
    }
}

这就是接口的内容 - 类以自己特定的方式实现其功能。

答案 2 :(得分:1)

我会选择一个房产。

enum PersonType
{
    American, Asian, European
}

interface IPerson
{
    string Name { get; set; }
    PersonType Type { get; }
}

American : IPerson
{
    public string Name { get; set; }
    public PersonType Type { get { return PersonType.American; } }
}

查询American s:

var americans = People.Where(p => p.Type == PersonType.American);

您可能应该为enum找到更好的名称,但这里的概念很重要,而不是名称。

答案 3 :(得分:1)

您所描述的任何内容都表明您可以从添加额外接口中受益。

即使实现不同,如果界面相同

  • 它有相同的公众成员
  • 公众成员在概念上做同样的事情

它仍然没有真正为你买任何东西。

接口的全部意义在于,即使类与外部世界的行为相同,它们也不一定具有相同的实现。这就是为什么它被称为Interface而不是Implementation

答案 4 :(得分:1)

根据某些值选择正确的混凝土类型非常适合工厂模式。我建议您实施工厂以选择正确的IPerson。另一方面,如果您打算对IPerson实施控制反转,那么最好编程到接口并采用多接口方法。

答案 5 :(得分:0)

可能不是。界面的要点是定义不同对象之间的相似性。如果你的算法必须知道每个IPerson是什么类型的人,那么你通过接口的抽象获得的收益很少。此外,如果您尝试创建一种新类型的IPerson并忘记为其填写案例,您的算法将会中断(可能以奇怪的方式)。

事实上,即使是带有开关的Type属性也可能不是最佳方法。您可能会发现有用的常见设计策略是Visitor Pattern