C# 在一个不在接口定义中的类中添加公共方法是一种好的做法吗?我应该什么时候做?
OOP概念不太清楚,可能是一个愚蠢的问题,请忽略它的愚蠢:-) 这个问题与下面的课程有关。在这里,我添加了一个公共方法“TestMethod()”,该方法没有在接口(下面)中定义C# 在一个不在接口定义中的类中添加公共方法是一种好的做法吗?我应该什么时候做?,c#,oop,interface,C#,Oop,Interface,OOP概念不太清楚,可能是一个愚蠢的问题,请忽略它的愚蠢:-) 这个问题与下面的课程有关。在这里,我添加了一个公共方法“TestMethod()”,该方法没有在接口(下面)中定义 这是个坏习惯吗?是否所有方法都必须在接口中定义 在哪些情况下,我可以在类中实现公共方法/成员,但不能在接口中实现 界面 public interface IAnimals { void MakeNoise(string noise); void Move(); string Color
public interface IAnimals
{
void MakeNoise(string noise);
void Move();
string Color
{
get;
set;
}
}
类实现
class Animal : IAnimals
{
private string color;
string IAnimals.Color
{
get
{
return color;
}
set
{
color = value;
}
}
void IAnimals.MakeNoise(string noise)
{
Console.WriteLine("Animal " + noise);
}
void IAnimals.Move()
{
Console.WriteLine("Animal moves");
}
public void TestMethod()
{
Console.WriteLine("test method in Animal class");
}
}
节目
class Program
{
static void Main(string[] args)
{
//Animal1 show methods and properties defined in the Interface
IAnimals animal1 = new Animal();
//Animal2 only shows the public method of Animal class
Animal animal2 = new Animal();
animal1.Color = "Red";
Console.WriteLine("Animal's color is " + animal1.Color);
animal1.MakeNoise("Barks");
animal1.Move();
animal2.TestMethod();
Console.ReadLine();
}
}
而输出
动物的颜色是红色的
动物吠声
动物动作
动物级试验方法
接口定义仅声明使实现符合“约定”的属性和方法 您的类中几乎永远不会只有在接口中定义的属性和方法,因为该类通常需要比一般契约实现更多的属性和方法
偏离接口的类定义中的一个好例子是实现
ICloneable
的类。您需要实现Clone
方法,但这并没有描述类的实际功能,它只是实现类与接口之间的契约。我的方法是这样的
一个类的目标应该是有一个责任(单一责任原则),它的公共契约(即公开访问的成员)应该与其履行的责任相关
我不会试图强制具体类公共成员和接口公共成员之间的关联。一个类可能有一个公共成员,以满足一个与它正在实现的接口契约无关但与实现细节完全相关的横切关注点。或者它甚至可以实现多个接口,或者一些对其职责没有任何意义的接口(例如IDisposable
)
这取决于您如何披露本合同,以确定这是否是一个潜在问题。我倾向于公开接口以提供行为,因为它允许我使用DI容器等来管理实现配置,这反过来又允许我模拟接口或为单元测试目的提供测试实现。这就是说,如果您正在处理具体类型(也是有效的“契约”),那么该类型的公共面将形成一个隐含契约,因此您需要小心更改它(就像您小心更改接口定义一样)
我从不特别担心我的类型拥有比接口更多的公共成员,但我确实会注意该类型试图做什么(并注意它试图做得太多的时候)
因此,我会回答说,审查一个类试图涵盖的职责并试图将其最小化是一种良好的做法,但我认为,这种公共成员比较并不是一种相关的“代码气味”警报。在某些情况下,一个类的存在主要是为了满足一个接口;如果一个类的存在是为了实现接口
IWuzzler
,对该类实例最自然的描述是“aWuzzler
”,那么最好让该类的公共面尽可能与接口匹配;一个成员在类中是有用的这一事实表明它可能是接口的[可能是可选的]部分
然而,在其他情况下,类将出于自身目的而存在,但将满足一个接口,这样它就可以由不太关心类所做的大部分事情的代码来操作。例如,许多集合类型可能实现
IEnumerable
,即使它们的主要目的是围绕着大多数IEnumerable
的消费者都不知道的事情。如果类实现接口的目的是使实例可供外部通用代码使用,则该类型应具有许多接口中不存在的成员。您能否定义是否在所有接口方法都显式实现时讨论?它们似乎出现在您的示例中,这使得问题更难回答(尽管Patrick做得很好)。这似乎是一个很好的选择,因为这不是一个真正的编码问题。@SimonWhitehead嗯,我知道需要实现接口的方法,但是,我的问题是什么时候在类中使用接口中没有定义的其他方法。因为,当我创建一个像IAnimals ani=new Animal()
这样的对象时,我只能看到IAnimal的成员。为了查看Animal
类本身的公共成员,所有实例必须是Animal
类型,比如Animal abc=new Animal()
。当然,但是您已经在类中显式实现了接口方法。所以,animalabc=newanimal();abc.Move()代码>是不可能的。“显式接口实现”在您的问题上下文中是否是一个参与者肯定会决定我如何回答您的问题。@SimonWhitehead我想说这是public void TestMethod()
,这里更值得关注。我为什么要这样做,在这种情况下,我将访问Animal abc=new Animal();abc.TestMethod()代码>而不是将它放在接口中并像调用IAnimals xyz=new Animal()那样调用它;xyz.TestMethod()代码>。我不知道我是否能说得更清楚:-)。