在不在接口定义中的类中添加公共方法是一种好习惯吗?我应该什么时候这样做?

时间:2014-11-12 10:39:55

标签: c# oop interface

对于OOP概念不太清楚,可能是一个愚蠢的问题,请忽略它的愚蠢: - )

这个问题与下面的课程有关。在那里,我添加了一个公共方法" TestMethod()",它没有在界面中定义(下面)。

  1. 这是一种不好的做法吗?是否必须在Interface?中定义所有方法?
  2. 在哪些情况下我可以在类中实现公共方法/成员,但不能在接口中实现?
  3. 界面......

    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();
        }
    }
    

    输出......

      

    动物的颜色是红色

         

    动物树皮

         

    动物移动

         

    动物类中的测试方法

3 个答案:

答案 0 :(得分:3)

我的方法会是这样的。

课程应该有一个责任(单一责任原则),其公共合同(即可公开访问的成员)应与其履行的职责相关。

我不会尝试强制执行具体类公共成员和接口公共成员之间的关联。一个类可能有一个公共成员,以实现与其正在实现的接口合同无关的交叉关注,但与实现细节完全相关。或者它甚至可能实现多个接口或某些不重要的接口(例如IDisposable)。

这取决于您如何披露此合同是否存在潜在问题。我倾向于公开提供行为的接口,因为它允许我使用DI容器等来管理实现配置,这反过来允许我模拟接口或提供测试实现以用于单元测试。也就是说,如果你正在处理具体的类型(也是有效的"合同")那么这种类型的公众面孔形成一个隐含的合同,所以你需要小心改变它(就像你想的那样)小心改变界面定义)。

我从来没有特别担心我的公共成员比接口有更多的公共成员,但我确实试着注意这个​​类型试图做什么(并注意它何时尝试做太多)。

所以我会回答一个好的做法是审查一个班级试图承担的责任并尝试将其最小化为一个,但我会说这个公共成员的比较并不相关"代码气味和#34;警报,在我看来。

答案 1 :(得分:2)

接口定义仅声明使实现符合'合同的属性和方法。

您几乎永远不会只在类中的接口中定义属性和方法,因为该类通常需要更多的一般合同实现。

类定义中偏离接口的一个好例子是实现ICloneable的类。您需要实现Clone方法,但这并不能描述类实际执行的操作,它只是实现了类与接口的合约。

答案 2 :(得分:0)

在某些情况下,主要是为了满足界面而存在一个类;如果为了实现接口IWuzzler而存在一个类,并且该类实例的最自然的描述将是“a Wuzzler”,那么拥有该类的公共面可能是好的尽可能匹配界面;一个成员在该类中有用的事实表明它可能有用作界面的[可选的]部分。

然而,在其他情况下,一个类将出于其自身的目的而存在,但是它将满足一个接口,以便可以通过不太关心该类所做的大部分事情的代码来操作它。例如,许多集合类型可能会实现IEnumerable<T>,即使它们的主要目的在于IEnumerable<T>的大多数消费者对此一无所知的事物。如果该类实现了一个接口,目的是使实例可以被外部通用代码使用,那么该类型应该具有许多在这些接口中不存在的成员。