面向对象(二)
一、 继承
1. 继承的类型
a) 相信这个大家都知道的,什么呢?实现继承和接口继承
b) 实现继承:
i. 就是一个类A派生于类B,A就具有了类B的非私有的成员字段和函数。
ii. 实现继承的优点是想给现有的类添加功能,或者有很多类想共享同一功能时。
例子:
类A有一个吃的方法,但是现在我们同时需要吃和跑的方法,我们就可以用B 继承类A,再添入跑的功能。这个时候B就是我们需要的。
一切生物都有“吃”的功能(不知道对不对),所以在类A有一个吃的方法,然后我们创建了Person类,Animal类,Plant类,因为这三个类都有吃的方法,所以可以都可以通过继承类A实现吃的方法。
c) 接口继承:
i. 就是一个类A 继承了一个接口,也就是说,仅仅继承了函数的签名,没有继承任何实现。
ii. 接口继承的优点用于需要指定该类型具有某些可用的特性
在C#当中既有实现继承也有接口继承
2. 继承的实现
a) 语法:
|
class ChildClass : BaseClass 其实在C#中所有的类都继承自Object 只不过编译器省略了Object class DemoClass :Object { //红色部分为省略的部分 } |
b) 构造函数
i. 在单个类中我们知道了构造函数的使用,但是在派生类中就不同于一个类了。因为继承会涉及一个层次构造的问题。
ii. 在你实例化一个派生类对象的时候,实际上会有多个构造函数出现。
iii. 一个基类 Person类,一个派生类Student类。大家知道在给一个类进行实例化的时候会调用该类的构造方法。所以,在Student类进行实例化的时候,首先编译器会调用Student类的构造方法,但是不会去执行,而是转到他的父类即 Person类的构造方法,然而仍然不会执行Person类的构造方法,而是继续向上调用,直到调用到Object类的构造方法,这时候执行Object类的构造方法,接着向下执行,。。。,执行Person类的构造方法,最后执行Student类的构造方法,Student类的实例对象创建完成!可以说一个类的构造方法执行一次就会产生一个该类的对象,所以在这个过程中一共产生了三个对象,object对象,person对象,student对象。大家想想这是为什么呢?请大家参看一下其它文章。
iv. 回答上面的问题既然派生类可以使用基类中的成员方法,如果不是在派生类的实例对象调用基类的成员方法之前就有一个基类的对象,那么派生类的实例对象又如何能够调用到呢!
v. 在这其实编译器又省略了代码,请看下面的例子:
|
class Person { Public Person():base() { } public void Say() { } } Class Student : Person { Public Student ():base() {//显示的调用基类的构造函数 } } |
vi. 有参数的构造函数
这里需要注意如果基类Person的构造函数显示给出,并且不同于默认的构造函数时,派生类必须要有和基类相匹配或者可以给基类的构造函数提供必要参数的构造函数。否则会发生错误。
c) 方法
i. 在方法里面重点和大家virtual 和 override
ii. 在C#中函数默认情况下不是虚拟的,但(除构造函数)可以显示的声明为虚拟。
iii. 关键字virtual 用于对一个类中可修改方法的声明,称为虚拟方法。用于实现多态。使用virtual修饰的方法在子类中被重写时需要使用关键字override
iv. 注意:使用virtual访问修饰符不能与static 和override等访问修饰符一同使用
v. 关键字override 用于修改方法,具有override关键字的方法是对基类中同名方法的新的实现,基类中的方法必须是virtual或abstract。
vi. 如果同名的方法在基类和派生类中都进行了声明,但是方法还没有声明为上面的virtual或override,派生类的方法就会隐藏基类的方法。执行的结果将是取决于用于引用实例的变量的类型,而不是实例本身的类型。可以说是依靠表达式左边。
|
例如上面的两个类 p.Say(); 调用的是基类Person的Say方法。 |
vii. New关键字用于显示的隐藏基类的方法
viii. 多态分为: 函数重载 和 动态绑定
3. 抽象类和抽象函数
a) 语法:使用Abstract关键字来对类或函数进行声明
b) 抽象类: 不能被实例化的类是抽象类。抽象类是派生类的基础。通过不实现或者部分实现,这些类用于创建模板。如果字类没有完全实现抽象类里面的方法,那么它仍然是抽象类。派生类实现抽象类的方法需要使用override来进行重写。
c) 抽象函数: 是虚拟的,而且只有函数的签名,没有具体的函数实现。必须在非抽象的类中重写。
4. 接口
a) 接口就是一种约束,实现接口的类必须遵守该约束。
b) 接口相当于抽象类,但是不能包含任何方法实现。
c) 使用接口应该注意:
i. 一般情况下,接口中只能包含方法,属性,索引器和事件的声明。
ii. 接口中不能包含字段,构造函数,和常量。
iii. 接口里面的东西默认都是public,用户不能自己显示的指定访问级别,否则会发生编译错误。
iv. 在接口中不能实现任何方法,属性,索引器
d) C#中允许继承多个接口,中间用逗号分开
e) 如果继承的两个接口中有一个相同签名的方法,这个时候就要显示的指出调用哪个。例子:接口名.方法
f) 接口可以继承接口
浙公网安备 33010602011771号