Abstract Class、Interface与继承

其实写这篇文章,我自己的想法也不是多么的靠谱,但是我却想写一下自己的想法,主题当然就是继承。

众所周知的事情就是,C#是不支持多重继承的,一个类只能同时继承一个父类,但是能够同时继承多个接口。那么,我们在规范一个类的时候,是给他写一个Abstract Class作为其父类,还是写一个Interface作为接口,这就要做出权衡。翻书翻资料能找到的抽象类与接口的区别是什么,说起来还真不多。抽象类可以给出一点方法的实现,而接口则不行;抽象类可以定义自己的属性,而接口只能声明静态字段;接口不能写出访问修饰符,最终它们将都是public的,而抽象类随意。

虽然区别已经列举出来了许多,但总起来讲,就是一句话:接口更有利于规范一个类的行为,而抽象类更倾向于规范一个类的属性。

比如说,我要为全世界上所有的人写一个类,那我就最好写一个抽象类,因为人是有很多属性的,比如性别、年龄、名字等等,而接口没办法做这个事情。那么这个类里面要写些什么方法呢,这个就有待考究了,政治书上写着“人类与动物的区别是人类能够制造工具并使用工具”,生物书上写着“人类是能够直立行走的动物”,但是我认为把这些东东放到这个最基本的基类中(这个类直接继承自object,不再考虑什么Animal之类的东西了)并不好,因此从我个人理解的角度上讲,这些东西可以放到接口里面,大不了让某个需要用到的类去继承那个接口就好了。

我想了想,人类共同都有的行为有什么,恩,对了,人都会挂,于是我写了个接口叫做IDieable,里面就一个方法,叫做Die(),然后我让Human去继承了这个接口,代码就成了这个样子:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
 1    public abstract class Human : IDieable
 2ExpandedBlockStart.gifContractedBlock.gif    {
 3        private int m_Age;
 4        public virtual int Age 
 5ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 6ExpandedSubBlockStart.gifContractedSubBlock.gif            get return m_Age; }
 7            set
 8ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 9                if (value >= 0)
10                    m_Age = value;
11            }

12        }

13ExpandedSubBlockStart.gifContractedSubBlock.gif        public abstract Sex Sex getset; }
14ExpandedSubBlockStart.gifContractedSubBlock.gif        public virtual string Name getset; }
15
16ContractedSubBlock.gifExpandedSubBlockStart.gif        IDieable Members#region IDieable Members
17
18        public virtual void Die()
19ExpandedSubBlockStart.gifContractedSubBlock.gif        {
20            Console.WriteLine(Name +" die");
21        }

22
23        #endregion

24    }

25
26    public interface IDieable
27ExpandedBlockStart.gifContractedBlock.gif    {
28        void Die();
29    }

30
31    public enum Sex : byte
32ExpandedBlockStart.gifContractedBlock.gif    {
33        Male = 0,
34        Famale = 1
35    }

 

后面我想派生出来一个子类,这个类用来描述一个女学生,这该怎么办呢?性别是人类的一个属性,职业对于一个正常人来说也算是一个属性,那么我应该建立一个抽象类“学生”继承自Human然后令“女学生”这个类继承“学生”然后改变它的Sex属性呢,还是建立一个抽象类“女性”继承自Human然后再写一个接口作为“学习”并令“女学生”分别继承“女性”这个抽象类和“学习”这个接口呢?这两者说起来都有理,我分别把它们的代码写了出来:

第一种,虚类型

 

ContractedBlock.gif ExpandedBlockStart.gif Code
    public abstract class Studet:Human
    {
        
public virtual void Study()
        {
            Console.WriteLine(Name 
+ " is studying!");
        }
    }

    
public class FamaleStudent : Studet
    {
        
public override Sex Sex
        {
            
get
            {
                
return Sex.Famale;
            }
            
set
            {
                
throw new NotSupportedException();
            }
        }
    }

 

第二种,虚类加接口型

 

ContractedBlock.gif ExpandedBlockStart.gif Code
    public abstract class Famale : Human
    {
        
public override Sex Sex
        {
            
get
            {
                
return Sex.Famale;
            }
            
set
            {
                
throw new NotSupportedException();
            }
        }
    }

    
public interface IStudyable
    {
        
void Study();
    }
    
    
public class FamaleStudent : Famale, IStudyable
    {

        
#region IStudyable Members

        
public void Study()
        {
            Console.WriteLine(Name 
+ " is Studying!");
        }

        
#endregion
    }
说起来,这两种哪个更好呢?我自己也不知道,学了这么多年了,也用了这么多年了,我对面向对象这东西还是稀里糊涂的,那些课本上的东西我算是背下来得差不多了,只是真正用的时候,我都不知道自己在用。刚才说的上面这两种,第一种省掉了一个接口,显得简洁明了;第二种用接口规范了行为,显得直观。真让我挑的话,我还是看中第一种,原因是什么,我自己都说不出来。今天我写这篇文章出来,也是希望有达人能为我指点一下,我可不希望得到的答案是“怎么都行”、“一个人有一个人的编程习惯”之类的答案唉……

转载于:https://www.cnblogs.com/wodehuajianrui/archive/2008/09/04/1284187.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值