接口、抽象或只是虚拟方法?
我有很多系统,我们称它们为A、B、C、D、E、F、G、H、I、J
。
它们都有相似的方法和属性。有些包含完全相同的方法和属性,有些可能略有不同,有些可能差异很大。现在,我每个系统都有很多重复的代码。例如,我有一个为每个系统定义的名为 GetPropertyInformation()
的方法。我试图找出哪种方法是减少重复代码的最佳方法,或者以下方法之一可能不是可行的方法:
Interface
public Interface ISystem
{
public void GetPropertyInformation();
//Other methods to implement
}
public class A : ISystem
{
public void GetPropertyInformation()
{
//Code here
}
}
Abstract
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)
I have a bunch of systems, lets call them A, B, C, D, E, F, G, H, I, J
.
They all have similar methods and properties. Some contain the exact same method and properties, some may vary slightly and some may vary a lot. Right now, I have a lot of duplicated code for each system. For example, I have a method called GetPropertyInformation()
that is defined for each system. I am trying to figure out which method would be the best approach to reduce duplicate code or maybe one of the methods below is not the way to go:
Interface
public Interface ISystem
{
public void GetPropertyInformation();
//Other methods to implement
}
public class A : ISystem
{
public void GetPropertyInformation()
{
//Code here
}
}
Abstract
public abstract class System
{
public virtual void GetPropertyInformation()
{
//Standard Code here
}
}
public class B : System
{
public override void GetPropertyInformation()
{
//B specific code here
}
}
Virtual Methods in a Super Base class
public class System
{
public virtual void GetPropertyInformation()
{
//System Code
}
}
public class C : System
{
public override void GetPropertyInformation()
{
//C Code
}
}
One question, although it may be stupid, is let's assume I went with the abstract approach and I wanted to override the GetPropertyInformation
, but I needed to pass it an extra parameter, is this possible or would I have to create another method in the abstract class? For example, GetPropertyInformation(x)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您的抽象方法和“超级基类”方法并没有太大不同。您应该始终使基类抽象,并且可以提供默认实现(虚拟方法)或不提供默认实现(抽象方法)。决定因素是您是否想要拥有基类的实例,我认为不需要。
所以它位于基类和接口之间。如果您的 A、BC 类之间存在强耦合,那么您可以使用基类和可能的通用实现。
如果 A、B、C 类自然不属于单个“系列”,则使用接口。
而且
System
并不是一个好名字。并且覆盖时无法更改参数列表。也许默认参数可以提供帮助,否则您只需要 GetPropertyInformation() 的 2 个重载。
Your abstract and 'super base class' approaches are not too different. You should always make the base class abstract, and you can provide a default implementation (virtual methods) or not (abstract methods). The deciding factor is whether you ever want to have instances of the base class, I think not.
So it's between base class and interface. If there is a strong coupling between your A, B C classes then you can use a base class and probably a common implementation.
If the A, B, C classes do not naturally belong to a single 'family' then use an interface.
And
System
is not such a good name.And you cannot change the parameterlist when overriding. Maybe default parameters can help, otherwise you just need 2 overloads for GetPropertyInformation().
通常,当您想要共享实现并减少重复时,您会选择对象继承。否则,接口会获胜,因为它们更加灵活,因为不需要公共基类。
至于重写方法并修改参数列表,这是不可能的。想象一下如何在基类或接口引用上调用该方法?
Generally you choose object inheritance when you want to share implementation and reduce what would otherwise be duplication. Otherwise interfaces win because they are more flexible since there is no need for a common base class.
As for overriding a method and modifying the parameter list that's just not possible. Imagine how you would call that method on a base class or an interface reference?
我会选择类似下面添加的内容。您仍然可以获得接口契约和共享实现的好处。
I'd go with something like what I've added below. You still get the benefit of the interface contract and shared implementation.
您不能在覆盖中传递额外的参数。当您重写时,您将使用确切的签名重写该方法。我建议您传入一个接口参数,例如 IPropertyInformation,该参数可以根据实现进行更改。
决定使用基类还是接口进行实现实际上取决于您的用途。 AI 彼此之间是否有足够的共同点,以至于它们真的应该都派生自同一个基类?如果是这样,则使用基类。真的只是
GetPropertyInformation
是共享的,否则系统在功能上完全不同吗?那么你真的只是希望他们共享一个界面。You cannot pass the extra parameter in the override. When you are overriding, you are overriding the method with the exact signature. I would suggest you pass in an interface parameter like
IPropertyInformation
that can change per implementation.The decision to go with a base class or an interface for your implementation really depends upon your use. Do
A-I
have enough in common with each other that they should really all derive from the same base class? If so, then use a base class. Is it really that justGetPropertyInformation
is shared and otherwise the systems are totally functionally different? Then you really just want them to share an interface.其他人已经涵盖了我的答案中最初的内容,但关于“添加参数”点:不要忘记最新的 C# 还允许您在方法中拥有可选参数。
Others have covered what was originally in my answer, but about the "adding a parameter" point: Don't forget that the latest C# also lets you have optional parameters in methods.
除非你有令人信服的理由,否则我会选择界面。公共虚拟方法虽然做了很多,但并不理想。
Unless you have a compelling reason otherwise, I'd go with the interface. Public virtual methods, though done a lot, is not ideal.