2011-09-28 54 views
8

我有一堆系统,我们打电话给他们A, B, C, D, E, F, G, H, I, J接口,抽象,或只是虚拟的方法?

它们都有类似的方法和属性。有些包含完全相同的方法和属性,有些可能略有不同,有些可能会有很大差异。现在,我为每个系统都有很多重复的代码。例如,我有一个为每个系统定义的名为GetPropertyInformation()的方法。我试图找出哪一种方法是减少重复的代码或以下方法也许一个最好的办法是不是要走的路:

接口

public Interface ISystem 
{ 
    public void GetPropertyInformation(); 
    //Other methods to implement 
} 

public class A : ISystem 
{ 
    public void GetPropertyInformation() 
    { 
     //Code here 
    } 
} 

摘要

在超基类
public abstract class System 
{ 
    public virtual void GetPropertyInformation() 
    { 
     //Standard Code here 
    } 
} 

public class B : System 
{ 
    public override void GetPropertyInformation() 
    { 
     //B specific code here 
    } 
} 

虚拟方法

public class System 
{ 
    public virtual void GetPropertyInformation() 
    { 
    //System Code 
    } 
} 

public class C : System 
{ 
    public override void GetPropertyInformation() 
    { 
     //C Code 
    } 
} 

一个问题,尽管它可能是愚蠢的,是让我们假设我去与抽象的方法,我想重写GetPropertyInformation,但我需要它传递一个额外的参数,这是可能的,或者我会在抽象类中创建另一个方法?例如,GetPropertyInformation(x)

回答

6

您的抽象和“超级基础”方法并没有太大的差异。你应该总是使基类抽象,并且你可以提供一个默认的实现(虚方法)或不提供(抽象方法)。决定性因素是你是否想要拥有基类的实例,我认为不是。

所以它介于基类和接口之间。如果您的A,B C类之间存在强大的耦合,那么您可以使用基类,也可能使用通用实现。

如果A,B,C类自然不属于一个“家庭”,则使用一个接口。

System并不是这样一个好名字。

而且重写时不能更改参数列表。也许默认参数可以帮助,否则你只需要2次重载GetPropertyInformation()。

+0

我有一种感觉,抽象和超级基类是相似的。 A,B,C系统确实具有强大的耦合。有一个行业标准,但不必遵循,所以每个人都可以采用标准或改变他们的标准。在匆忙中,我选择了系统:) – Xaisoft

+0

顺便说一句好话。 – Xaisoft

3

一般情况下,如果您想共享实施并减少原本会重复的内容,请选择对象继承。否则接口会赢,因为它们更加灵活,因为不需要共同的基类。

至于重写一个方法和修改参数列表是不可能的。想象一下,你将如何在基类或接口引用上调用该方法?

+0

它是“可能的” - 你应该能够声明这样的方法,它不再是原始方法的重写。 – millimoose

+2

@Sii当然是不可能的。问题要求*重写*方法并添加一个参数。这是不能做到的。 –

+0

我有一种感觉无法完成,一厢情愿的想法。 – Xaisoft

3

我会像下面添加的东西一样。您仍然可以从界面合同和共享实施中获益。

public Interface ISystem 
{ 
    public void GetPropertyInformation(); 
    //Other methods to implement 
} 

public abstract class System : ISystem 
{ 
    public virtual void GetPropertyInformation() 
    { 
     //Standard Code here 
    } 
} 

public class B : System 
{ 
    public string ExtendedSystemProp {get;set;} 

    public override void GetPropertyInformation() 
    { 
     base.GetPropertyInformation(); 

     var prop = "some extra calculating"; 

     GetExtraPropertyInformation(prop); 
    } 

    public void GetExtraPropertyInformation(string prop) 
    { 
     ExtendedSystemProp = prop; 
    } 
} 

ISystem genericSystem = new B(); 
genericSystem.GetPropertyInformation(); 

(genericSystem as B).ExtendedSystemProp = "value"; 
+0

你能详细说明为什么你会这样做吗? – Xaisoft

+0

这样,即使只使用ISystem接口进行编程时,您仍然可以获得所有属性(当您拥有它们时应该这样做)。但是,如果您在仅存在B的上下文中进行编码:'B bSystem = new B();'您还公开了'B'特定方法以供明确使用。 – scottm

2

您无法在覆盖中传递额外的参数。当你压倒一切时,你会用确切的签名覆盖方法。我建议你传入一个接口参数,如IPropertyInformation,每个实现可以更改。

决定使用基类还是接口来实现您的实现取决于您的使用。 A-I是否有足够的共同点,他们应该真的都来自同一个基类?如果是这样,那么使用基类。是否真的只是共享GetPropertyInformation,否则系统在功能上完全不同?那么你真的只是想让他们分享一个界面。

2

其他人已经涵盖了我的答案中最初的内容,但关于“添加参数”一点:不要忘记,最新的C#还允许您在方法中使用可选参数。

+0

但我必须在开始时声明可选参数。我可能不知道我需要一个参数,直到1年后,所以在这种情况下,可选参数对我没有好处。 – Xaisoft

2

除非你有一个令人信服的理由,否则,我会去接口。公共虚拟方法虽然做了很多,但是是not ideal