一、答案
面向对象的语言具有继承性、封装性、多态性。
这一小节的内容均来自本人对《你必须知道的.NET 王涛著》的解读。
二、继承
1、概念
继承,就是面向对象中类与类之间的一种关。继承的类称为子类、派生类;而被继承的类称为父类、基类或超类。通过继承,使得子类具有父类的属性和方法,同时子类也可以加入新的属性和方法或者修改父类的属性和方法建立新的类层次。
继承机制体现了面向对象技术中的复用性、扩展性和安全性。为面向对象软件开发与模块化软件架构提供了最基本的技术基础。
在.NET中按其实现方式分两种继承
(1)实现继承:基类继承父类的所有方法和属性,并且只有一个基类。
(2)接口继承:继承多个接口,派生类只继承了方法签名而没有实现,具体的实现必须在派生类中完成。实际就是接口实现。接口继承的优点是实现了对象与行为的分离。
2、继承本质论
(1)对象的创建过程
Bird bird创建的是一个Bird类型的引用,而new Bird()才完成的是创建Bird对象(分配内存空间和初始化操作),然后将这个对象的引用赋给bird变量这样就建立了bird变量与Brid对象的关联。
(2)从继承的角度分析CLR如何执行对象的创建过程
对象的创建分字段的创建和方法的创建。
首先是字段,对象一经创建,首先会找到其父类的字段被为其分配存储空间,它是按照顺序完成对整个父类及其本身字段的内存创建,并且字段的存储顺序是由上到下排列,最高层类的字段排在最前面。
然后是方法,需要明确一点的是方法表的创建是类第一次加载到AppDomain时完成的(应该理解成方法表先于对象的创建)。在创建对象的时候只是将其附件成员TypeHandle指向方法列表在LoaderHeap上的地址,将对象与其动态方法列表相关联起来。
3、题外话
这种情况下,bird.ShowType()输出是什么呢?我们需要注意一下两个原则:
(1)关注对象原则-----调用子类还是父类的方法,取决于创建的对象是子类的对象还是父类的对象,而不是它的引用类型。
bird.ShowType()调用的是Chicken类的方法。
(2)执行就近原则
对于同名字段或方法,编译器是按照其顺序查找来引用的,也就是首先访问离它船舰最近的字段或者方法。
注意:在子类方法中,如果标记new关键字,则意味着隐藏基类实现,其实就是创建了与父类同名的另一个方法,在编译中这两个方法处于动态方法表达不同地址位置,父类方法排在前。
二、封装
1、什么是封装
简单地说,封装隐藏了类内部的具体实现细节,对外则提供统一访问接口来操作内部数据成员。
2、字段、属性和方法
(1)字段-----通常定义为Private,表示类的状态信息。字段是可读可写的,需要注意的是只读字段只能在构造函数中赋值或者这样声明(private readonly int Num=1;)。那么为什么字段一般不设为Public呢,因为用public修饰的字段,类的实例可以访问它,这样就容易破坏对象的状态信息,数据安全性和可靠性无法保证。
(2)属性-----通常定义为public,表示类的对外成员。通过公共属性的访问来实现对类状态信息的读写控制,主要有两点好处:一是避免了对数据安全的访问限制和内部数据的可靠性;二是避免了类扩展或修改带来的变量连锁反应。
(3)方法-----封装了类的行为,提供了类的对外表现。用于将封装的内部细节以供有方法提供对外接口,从而实现与外部的交互与响应。
3、封装的意义
(1)隐藏系统实现的细节,保证系统的安全性和可靠性。
(2)提供稳定不变的对外接口。
(3)封装保证了代码模块化,提高了软件的复用和功能分离。
三、多态
在面向对象中,多态是指两个或多个属于不同类型的对象,对用一个消息(方法调用)做出不同响应的能力。其实继承和重载就实现了多态。
也可以这么理解,多态是指为同名的方法提供不同的实现能力,它使得我们不用关心方法的具体实现而仅仅依靠其名称来进行调用操作。