举个例子!
小学生:打乒乓、踢足球、打篮球、过家家
中学生:打乒乓、踢足球、打篮球、谈恋爱继承关系如下:
学生
{
打乒乓、踢足球、打篮球
}
小学生:学生
{
过家家
}
中学生:学生
{
谈恋爱
}父类学生中:打乒乓、踢足球、打篮球三个函数的代码和小学生、中学生是一样的。
这种情况是应该用接口还是类?
用接口的话,对于多层架构来说比较好,但是代码又是一样的,觉得很浪费。

解决方案 »

  1.   


    如果遇到多重继承的时候,你就不得不使用接口。因为.net是不支持多重继承的。除此以外,不必太在意是用接口还是类。当你写成学生类,但是发现其它地方又需要学生接口,也没有关系。如果一定需要学生类也具有学生接口,直接给学生类声明上使用学生接口的定义然后重新编译就可以了,学生类和学生接口并不冲突。
      

  2.   

    我非常喜欢vs的重构功能(从Refactor菜单进入)。它就可以自动把类再抽象出接口来。重构,而不需在一开始写程序时纠缠于设计细节。
      

  3.   

    如果用抽象类+接口,怎么通过接口来实例化类?using System;
    namespace my
    {
      interface 行为
      {
        void 吃();
        void 睡();
      }
      abstract class 动物 : 行为
      {
         public virtual void 吃()
         {
            Console.WriteLine("我们的动物是会吃的,不是玩具!");
         }
         public virtual void 睡()
         {
           Console.WriteLine("我们的动物是会睡的,不是玩具!");
         }
      }
      class 猴子 :  动物
      {   
         public override void 睡()
         {
           Console.WriteLine("我是一只猴子所以要在树上睡!");
         }
         public void 跳()
         {
           Console.WriteLine("我是一只猴子所以要跳来跳去的!");
         }
       }
      class myClass
      {
         public static void Main()
         {
           //关键就是这里,请问能用接口来实例化类吗?
            //比如:行为 i = new new 猴子();
            猴子 b = new 猴子();
           b. 睡();
           b. 吃();
           b. 跳();
         } 
      }
    }
      

  4.   

    举个例子吧!    interface if
        {
            void eat();
        }
        class dog:if
        {
            public void eat()
            {
                //吃东西
            }
        }那么可以:
    if i = new dog();
    i.eat();如果用抽象类+接口的话:    interface if
        {
            void eat();
        }
        
        class abstract animal : if
        {
            public void eat()
            {
                //吃东西
            }
        }    class dog : animal
        {
            public void drink()
            {
                //喝东西
            }
        }这个时候怎么写?下面这样还可以吗?
    if i = new dog();
    i.eat();
    i.drink();
    貌似不可以了吧!??如果我想让别人通过接口来访问的话,应该怎么办?谢谢sp1234
      

  5.   

    你给别人的接口就文不对题。你给人家一个if接口(且不说这个if是非法命名的问题),但是这个接口根本没有drink定义啊?这是你的问题,不是代码的问题。所以,接口就是抛开实现,先让你把定义说清楚。免得你给人家一个错误的类型让人家执行莫名其妙的功能。
      

  6.   

    我给你举一个例子:using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    using System.Threading.Tasks;
    using System.Threading;namespace ConsoleApplication1
    {
        interface IStudent
        {
            void think();
        }    abstract class animal
        {
            public void drink()
            {
                Console.WriteLine("drink");
            }        public void eta()
            {
                Console.WriteLine("eta");
            }
        }    class dog : animal
        {
            public void fuck()
            {
                Console.WriteLine("fuck");
            }
        }    class Csdn用户 : animal, IStudent
        {        public void think()
            {
                Console.WriteLine("think");
            }
        }    public class test
        {
            static void Main()
            {
                animal x = new Csdn用户();
                x.drink();
                Console.ReadKey();
            }
        }
    }
    这里你才可以给别人一个animal让他去执行dring方法。
      

  7.   

    不需要那么多using,只要有第一个就可以。如果运行时出错,删除后边的using。
      

  8.   

    我们还可以对一个对象的两种类型身份进行操作:public class test
    {
        static void Main()
        {
            animal x = new Csdn用户();
            x.drink();
            IStudent y = (IStudent)x;
            y.think();
            Console.ReadKey();
        }
    }
      

  9.   

    楼主前面举的那个if接口,是一个例子而已,他应该知道那个不能取IF这种关键字
    呵呵
      

  10.   

    当你的项目的复杂程度还没有达到这个地方需要接口的时候,就不需要设计接口。接口可以在重构中添加,不需要过早提及。你总是单向思维。知识其实不是一颗树,任何类型其实都有很多个父类。可是.net这种弱智语言从java学来的毛病,不支持多重继承(如果你读10年前的书籍,可以看到很多那时候的作者鼓吹避免使用继承)。现在,假设你的软件因为需求更加自然丰富而变得复杂了,不仅仅是一些注册用户可以做版主,在你的网站上登记的宠物也可以做版主,他们不需要通过注册用户注册,只要进入宠物专用的版面就可以行使版主的职责,怎么设计?这就叫做多重继承。你原来的设计中,版主类继承自普通注册用户类,宠物类继承自动物类,现在需要版主和宠物都有版主职责,也就是都具有版主的(包括特定的属性和方法的)接口,你难道不去实现用户需求,你难道去像很多程序员所犯的错误那样去跟用户争论宠物该不该是版主的问题?当你争辩的时候,其背后的动因就证明你不懂如何多重继承。
      

  11.   

    请记住,接口可以在重构中添加。如果你在某个类型上不需要接口,不证明你的烦躁是对的,只能证明你的系统所描述的自然界知识还是最单纯初等的。等你需要复杂一点的知识,就需要接口来了。有许多著名的纯OOPL,也有几十年历史,它们没有接口,支持多重继承,于是就没有这种纠缠。
      

  12.   

    避免重复是很重要一项原则,如果可能,请尽量避免代码的冗余,不然会给以后维护扩展带来问题。
    use one way do one thing
      

  13.   

    最后我要补充一句,我其实也很不赞成为了类型继承而类型继承,为了接口而接口。也就是仅仅为了少写几个代码,以为只要是属性定义或者方法定义比较像,而使用接口或者继承,那是极端错误的。我在帖子《大家看看我对类的继承理解的怎么样》有一个简单描述。其实对于class或者interface,我都是认为应该避免我们设计出来的继承结构跟用户的概念抽象方式不同。
      

  14.   

    -----------------
    sorry,其实这段回复是说给楼主听的,他需要根据自己的情况作出抉择,但是知道一些基本的原则是对做出抉择很有帮助的。
      

  15.   

    小学生:打乒乓、踢足球、打篮球、过家家
    中学生:打乒乓、踢足球、打篮球、谈恋爱 这个先要做一个基本判断:
    [1]小学生与中学生之间是否有依赖关系
    [2]打乒乓、踢足球、打篮球、过家家、谈恋爱,这些动作之间是否有依赖元素存在
    [2-1]打乒乓、踢足球、打篮球之间是否有依赖元素存在就这个CASE而言,没有其它附属条件被表达,
    最好是采用集口,如果动作之间是无关的,最好是采用最小单位的接口
    3+1+1个接口
    打乒乓、踢足球、打篮球之间有关系的
    2+1+1个接口如果动作本身是有演化关系的,
    比如小学“会踢”,中学一定“会踢”,
    那么可以采用:
    抽象基本+接口实现的方式考虑两个原则:
    这些动作是否还可以细分,
    如果可以细分,有没有共同属性,
    接口的粒度
    接口也要考虑继承关系
    哪些动用是虚的,哪些是实的,要进行比较,
    是否将来会有新的要素加入,比如性别,年令。总之:
    主要是判断依赖倒置的原则,在这个CASE中是否存在,
    然后判断是否采用接口的实现方案
      

  16.   

    我来看sp1234的
    难得sp1234今天说的这么多,楼主有福啊~
      

  17.   

    对的 相当幸福 记得以前刚上csdn的时候对sp1234印象就很深刻