C# 面向对象之概念理解(3)

时间:2022-01-29 09:21:40

多态

多态是指两个或多个属于不同类的对象,对同一个消息(方法调用)做出不同响应的能力。

多态(《韦氏大词典》)中定义:可以呈现不同形式的能力或状态。

C#如何实现多态的知识——即继承上覆载。继承和覆载合起来实现了多态。

多态的优点:降低了在应用程序分发后,需求发生不可避免的改变时在已存在应用中导致的连锁反应。

还记得上一节那个“多重继承”吗?那对象应该如何表现出两个或多个不同对象类型的行为?

抽象类

抽象类用来列举一个类所需要的行为,但不明确提供每个行为的具体实现方法。只要一个类包括一个或多个抽象方法,该类就必须是抽象类,定义抽象类的手段是在类声明中加上abstract关键字。

注意,抽象类中的方法并不一定都是抽象方法;抽象方法也可容纳有方法体的方法,或称具体方法。

抽象类有什么限制吗?

对于抽象类有一个限制:它们不能被实体化。

何时用抽象类?

对于那些我们不能(或不愿)给出普遍实现的行为。

派生类没有实现所有的抽象方法会怎么样?

如果派生类没有从抽象类继承下来的所有抽象方法提供具体实现,则派生类自动被当做抽象类处理。此派生类不能被实体化。

接口

抽象类中可以定义私有attribute,私有的操作。当我们不打算规定将来派生类必须使用怎样的数据结构来实现期望的公共行为,就可以考虑接口。接口可以共同定义应用程序中的一个角色的意义(能进行的操作)。当然接口可以是公共的,也可以是私有的,不过一般都声明为公共的。接口中的方法都隐含地是公共机抽象方法。

继承被看做是一种“is  a”关系,接口也被看做另一种“is  a”关系。

 抽象类vs接口

  1. 从程度上看,接口要比抽象类更为抽象(而抽象类则比具体类来得抽象)。
  2. 当从一个抽象类派生出一个非抽象类时,派生类通过覆载的手段,通过抽象方法的具体实现。
  3. 当一个类实现一个接口时,该实现类也要提供接口中声明的所有方法具体实现。然而,实现类并不覆载它们(抽象类中多数用的是重写实现)。
  4. 抽象类派生的类不一定要覆载所有的抽象方法、提供具体版本;如果一个或多个抽象方法没有被覆载,则该派生类也是一个抽象类;
  5. 实现一个接口的类必须提供接口所需的所有抽象方法的具体版本;实现一个接口,是一种“要么全要,要么不要”的事情。
  6. 两者之间的另一个重要区别在于,一个类只能从一个基类派生,而一个类却可以实现多个接口。

实现多个接口时遇到相同的方法签名时怎么办?

如果一个类实现的两个货多个接口中的方法拥有同样的方法签名,则在实现类中只需要实现其中一个——该方法同时满足所有接口的实现要求。

接口的优势

当一个类同时扩展单个基类和实现一个或多个接口时。编译器仅将冒号后的第一项看作基类,列表中后面的一切都被假定为接口。接口不能被实体化,因为接口中没有构造器,虽然不能实体化一个接口,但却能把引用变量声明为一个接口类型。

一个类实现了超过一个接口,它的对象就有能力扮演应用程序中的多种身份或角色;这样的对象可以为不同类型的引用变量所维系。这个概念等同于作为一个人的你,被不同人当做不同角色看待的情形:在经理眼里你是雇员,在父母眼里你是孩子,在孩子眼里你是父母等等。

例如:

Iteacher t=new Professor();(现在知道为什么允许了吗?)

Professor类实现了Iteacher接口,教授就是教师,所以这种赋值是被允许的。从编译角度来说,如果等号的表达式的类型与左边变量的类型匹配,编译器就允许赋值操作,显然编译器是认为类型是匹配的。

接口的应用:

只要有可能,就应该吧类的公共部分设计为接口,而不是设计为特定的类类型,这样就可以让方法在多个方面拥有更更多灵活性。

Ps:抽象类和接口定义对象的任务,而无须陷入定义对象如何实现其任务的麻烦中区,以及为什么需要这么做。就好比规定人吃饭而不管你怎么样吃!(细嚼慢咽、狼吞虎咽)。当然和上面的多态、继承也是有关系的。