面向对象
OOP(面向对象技术)的三大特征:封装、继承和多态。
封装
封装:封装是OOP编程中的一个重要手段,就是指把具体实现的逻辑细节在内部隐藏起来,对外部只暴露公共的、规范的接口和调用方法,从而隐藏实现细节,使在使用的时候不用去考虑其内部的运作模式等等具体细节,以后即使是要修改其逻辑也不会影响外部调用的。封装,主要是为了降低组件之间的耦合度,以提高扩展性和维护性。比如:属性、方法等。
继承
继承:所谓继承,子类拥有父类一份copy的性质。使用继承机制可以提高软件模块的可重用性和可扩展性,从而提高软件的开发效率。
继承的性质:
1.子类中可以继承父类中除用private修饰的所有成员。
2.成员覆盖。有时并不希望派生类一成不变地继承基类中的所有成员,可以在派生类中使用new关键字,new关键字作用在于在子类中隐藏、覆盖基类中的成员,但要和基类中定义的成员的标示符相同。(即,使用关键字new可以覆盖基类中同标识的成员)。new关键字放在访问限制修饰符的前后均可,但一定要在成员的类型说明之前。要和创建对象时使用的new操作符区分。
3.base关键字:即使在覆盖了基类成员之后,有时仍希望在派生类中可以访问基类的原始成员,在C#中base关键字提供了这个功能,用于在派生类中访问基类被覆盖的成员。
注(1)为了避免层次结构过于复杂,C#中的类不支持多继承,即不允许一个派生类继承多个基类,只有在类和接口之间可以实现多实现。(2).NET类库是一个典型的面向对象的实现:System.Object类是其他所有类的基类,而所有的C#数据都是从类中衍生而来的。
多态
多态:多态性这一术语来源于生物系统,意指同一事物在不同的条件下可以表现不同的形态。在.NET中,多态指同一操作作用不同的实例,产生不同运行结果的机制。
虚方法
将基类的方法成员定义为虚拟方法(使用关键字virtual修饰),在派生类中对虚拟方法进行重载(使用关键字override修饰)。与覆盖相比,虚拟+重载的优势在于它能够实现运行时的多态性。
虚方法实现多态的性质:
1.类成员的虚拟只能用于方法,不能用于字段。
2.在基类中定义虚拟方法,实际上暗示了希望在派生类中继承并实现该方法,因此虚拟方法不能是私有的,而派生类对重载方法的访问限制应与基类中的虚拟方法相同,即要么都是public,要么都是protected。
3.基类中定义的虚拟方法要和派生类中重载方法的返回值类型、方法名、参数列表均相同。
4.用override重写的方法,依然是虚方法,可以继续被重写。
抽象类和抽象方法
抽象类:
抽象类表达的是抽象概念,它本身不与具体的对象相联系。抽象类的用途是提供一个公共的界面,而让派生类实现具体内容。使用abstract关键字声明抽象类和抽象方法。
1.抽象类中不允许定义抽象字段。
2.抽象类中的构造函数:在抽象类中是允许定义构造函数的,如果用户未定义则系统会为抽象类自动生成一个没有参数的构造函数;当抽象类中只定义了带参数的构造函数,则在其派生类中必须显示的调用基类中的构造函数。
3.不允许创建对象即类的实例。但可以将抽象类与非抽象的派生类实例相关联。
4.抽象类之间可以进行继承,如果抽象类中定义了抽象方法,那么其所有派生类都必须继承这些抽象方法;如果派生类不是抽象类,它就必须重载这些抽象方法并提供实现代码。
定义:[修饰符] abstract class 类名{}
抽象方法:
1.包含抽象方法的类必须是抽象类(即抽象方法一定属于抽象类,但抽象类不一定要包含抽象方法。)
2.抽象方法不能是私有的,而且抽象方法及其重载方法的访问限制应当相同。
3.抽象方法中没有代码,也没有大括号。即抽象方法不提供代码的实现。
4.基类中定义的抽象方法要和派生类中重载方法的返回值类型、方法名、参数列表均相同。
定义:[修饰符] abstract 数据类型/void 方法名([参数列表]);
实现:[修饰符] override 数据类型/void 方法名([参数列表]){}
密封类和密封方法
密封类
作用:有时候,我们并不希望自己编写的类被继承。或者有的类已经没有再被继承的必要,这就引入了密封类。
密封类不允许从中派生出其他的类。密封类通常位于类的继承层次的最底层,或者是在其他一些不希望类被继承的情况下使用。
定义:[修饰符] sealed class 类名{}
密封方法
作用:派生类重写了基类中的虚方法后,如果不再希望继续派生下去的类来重写该方法,于是就引入了密封方法。即密封方法能够起到“截止”多态性地作用。
密封方法所在的类不一定是密封类,而如果该类存在派生类,那么在派生类中就必须原封不动地继承这个密封方法,而不能在对该方法进行重写。
密封方法不能被重写,密封方法本身要求是一个重载方法,即sealed和override必须在方法定义中同时出现。
定义格式:[修饰符] sealed override 数据类型/void方法名([参数列表]){ }
接口
接口:是更高意义上的类的抽象。
用法:
1.接口主体只限对方法、事件、索引器以及属性的声明。接口中不能包含字段、构造函数和常量等。
2.接口成员是隐式公开的,如果对其显示指定访问级别,就会出现编译错误。
3.在接口中不能实现任何方法、事件、或者索引器。在指定方法时,只需给出返回类型、名称和参数列表,然后以分号结束。
4.派生类必须对接口中的所有成员进行重写。在派生类中重写接口成员,可以使用关键字virtual或者什么都不使用,仅此两种。(注:可以用virtual定义的虚拟方法去实现接口中定义的方法,但不能override去实现)。
5.在派生类中重写接口成员,要求派生类中重写成员的访问修饰符为public并且要和接口中的成员在,返回值类型、方法名、参数列表均相同。
接口是一组规范、一种标准,必需实现接口才能实现某种功能。典型的应用就是将接口作为参数时,要传递一个实现接口的对象,另一个就是将接口作为返回值,实际上要返回的也是实现了接口的对象。