一、abstract
abstract 的词义是“抽象”,它用来定义抽象类。抽象类不能被实例化只能被继承。
定义抽象类的格式如下:public abstract ClassName{……}
注意:只有基类成员声明为virtual或abstract时,才能被子类重写;而如果子类想改变虚方法的实现行为,则必须使用override关键字。
二、接口
出现缘由:由于c#语言不支持类的多重继承即一个类在定义时最多只能声明一个父类,因此,如果某个类需要继承多方面的行为时,抽象类或父类就不能满足条件了。故诞生了接口,一个类在定义时可以继承或者说实现多个接口。
相关细节:
》接口像类一样声明,是引用类型 ; 接口里面的成员可以包含方法的签名(方法签名指方法名、形参类型,以及形参的数量和排列顺序)、属性、事件和委托,但在接口中不可以定义数据成员(字段)和静态成员。与类不同的是,接口中的方法仅仅是他们的声明,并不提供实现。因此可以这样说:接口是函数声明的集合,封装了一些类共有的行为(方法)。如果类或结构从一个接口派生,则这个类或结构负责实现该接口中所声明的所有成员。一个接口可以从多个接口继承,一个类或结构可以实现多个接口。实现接口,就是在类中依次把接口中的方法全部写完整,即每个都补上方法体(花括号及里面的代码部分)。实现接口的类可以把它当做接口的子类,而接口可以认为是他们的父类。
》接口声明格式: 【属性】【修饰符】interface 以大写字母I开头的接口名 【:基接口】
》接口中每个成员的声明后必须加分号,不能包含任何实现;属性{ }后不用加。
》接口内的成员声明不能包含任何修饰符,所有接口成员的访问方式自动是public;
》在声明一个类来实现一个接口时,如果该类还要显示声明基类(即继承自某个父类),则基类和接口之间要有逗号分开,且基类写在前面。区别在于,一个类只能从一个基类派生,但可以实现多个接口。
》接口的继承:定义完接口后,如果有类想继承该接口,则它必须实现接口中定义的所有方法。派生接口继承了基接口中的函数成员说明。接口允许多重继承,一个派生接口可以没有基接口,也可以有多个基接口。在接口声明的冒号后列出被继承的接口名字,多个接口名之间用逗号分隔。
》如果基类实现了某个接口,则其接口成员就不能在该基类的派生类中实现了。基类也可以在接口成员上添加virtual关键字,这时,派生类就可以通过重写来实现这些接口成员。可以参照基类的重写.
》若类要实现某个接口,则必须实现该接口里的所有接口成员;
》如果一个类实现了多个接口,并且有些接口里的成员的签名和返回类型相同,那么,在类中只需要实现一个就能满足所有相同的了。
》接口和as运算符:如果我们尝试将类对象引用强制转换为类未实现的接口的引用,则会抛出一个异常,那么as运算符就是为了避免这个问题(即使转换不了也不会抛出异常而是返回null)。
格式:接口名 变量名=类对象名 as 接口名;这时,如果类实现了接口,表达式返回指向接口的引用,若未实现,表达式返回null而不是抛出异常;
》实现接口有两种方式,隐式和显示。采用隐式接口实现时,类或接口都可以访问接口中的方法;而若采用显示接口实现方式,实现接口的类中的接口方法不能使用任何访问修饰符,都默认为私有。接口方法只能通过接口来完成访问,都不能通过类的对象访问,正确的访问方式是把类对象再显式地转换为对应的接口,通过接口对象来调用方法 。如:IPerson per=(IPerson) USAPerson; per.Speak();
》当类实现单个接口时,通常使用隐式接口实现方式,这样类的对象可以直接去访问接口方法。
》当类实现多个接口且不同接口中有相同方法签名和返回类型的方法时,则使用显示接口实现方式。即使没有相同的方法啊签名,在实现多个接口时,仍推荐使用显示接口实现方式,因为这样可以标识出哪个方法属于哪个接口。
》接口在类中实现后,调用接口中实现了的方法有两种:
一是创建该类的对象,用 对象名.接口成员即可,就像用对象调用自己类中的方法一样;
二是先把类对象引用强制转换为接口类型来获取指向接口的引用,再用点运算符调用接口的方法。从类对象引用获取接口引用的格式: 接口名 变量名=(接口名)类对象名;如 IAnimal animal = (IAnimal) myDog ;
然后就可以用 变量名.方法名 来调用接口里的方法,如 animal.Eating();
》派生类的基类中,若有与其接口相同的方法等的实现,则在派生类中不必再次重申。
》显式接口实现:即在实现接口的类中,通过在方法名等前加接口名和点。它是为了希望每个接口分离实现,并且只可以通过指向接口的引用来访问;
三:抽象类和接口的区别,何时用抽象类何时用接口
关于这个方面,自己还没有清楚地认识,因为自己用的少,见得少,以后再补充。这里有一篇相关的博客应该可以对其有个大概的认识:http://www.cnblogs.com/huihui-gohay/archive/2009/12/13/1623070.html。
这篇文章的重点如下:
1、解释了“面向对象编程”和“面向接口编程”两个词的大致关系:面向接口编程是面向对象编程的思想精髓之一。还解释了面向对象:面向对象思想的核心之一,就是模拟真实世界,把真实世界中的事物抽象成类,整个程序靠各个类的实例互相通信、互相协作完成系统功能,这非常符合真实世界的运行状况,也是面向对象思想的精髓。
2、接口的作用:接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是……则必须能……”的理念。
3、面向接口编程实践:大致表达比如定义一个属性或字段的类型,一个方法的参数类型,如果可以用接口或抽象类代替具体类,那就用接口或抽象类。
4、对二者如何选用:“如果单从具体代码来看,对这两个概念很容易模糊,甚至觉得接口就是多余的,因为单从具体功能来看,除多重继承外(C#,Java中),抽象类似乎完全能取代接口。但是,难道接口的存在是为了实现多重继承?当然不是。我认为,抽象类和接口的区别在于使用动机。使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性。所以,如果你在为某个地方该使用接口还是抽象类而犹豫不决时,那么可以想想你的动机是什么。”
5、另一点区别:“再者,我认为接口和抽象类的另一个区别在于,抽象类和它的子类之间应该是一般和特殊的关系,而接口仅仅是它的子类应该实现的一组规则。”
最近对这两个东西挺迷惑,在了解设计模式相关知识时,参考的两本书中,有在讲同一个模式时,一个类图用的抽象类,一个用的接口,故懵逼了。以后有时间有心情再看看c#相关基础知识,再来继续完善补充。