【.Net基础拾遗】品味OO继承
0X1 引言

提起面向对象,每个人都有不同的见解。但提的最多的无非就是:对象、封装、继承、多态。差不多就是这些元素构成了面向对象设计开发的基本逻辑。面向对象编程,“对象”指的是什么?这里的"对象"可不是指“异性对象”,而是我们在开发中常常使用的:类。
0X2 对象
出生:对象就像个人的人,生而入世,死而离世。首先我们看看一个对象是如何产生的呢?在执行New操作后,系统首先会在内存中为其分配一定的内存空间,然后初始化其附加成员,调用构造函数执行初始化,这样一个函数就完成了初始化。
Person person=new Person("大壮他哥",25);
旅程:在某种程度上就是外界通过方法与对象交互,从而达到改变对象状态信息的过程。这也和人的生存之道暗合。
person.ChangeAge(26)
权限:我们都知道继承,儿子可以继承父亲的姓氏、基因、财产和一切可以遗留的东西,但并不代表就可以继承所有。因为父亲有一些隐私的部分为父亲独有,不可继承。所以,我们就需要在程序中标识哪些可继承或不可继承(这里的继承可以理解为访问权限)。.Net框架为我们内置了五种访问权限:
- public:最高访问权限,公司的董事会具有最高的决策权与管理权;
- protected:部门经理,具有对本部门的直接管辖权,面向对象中体现为子类继承纵向关系的访问约定;
- internal:类似于公司的职能部门的职责,不管是否具有上下级关系,人力资源部都有管辖其他部门员工的能力;(面向对象中体现为同一程序集的访问权限,只要是隶属于同一程序集,对象即可访问其属性等,不管是否存在隶属关系;)
- protected internal:副总经理,从横向到纵向都有管理权;
- private:最低访问权,公司一般职员,管好自己即可;
0X3 继承
什么是继承?

图1 继承关系图
继承,就是类与类之间的一种关系。继承的类成为子类(图1中小车和飞机就成为子类)、派生类。而被集成的类则成为父类、基类或超类。通过集成,使得子类拥有父类中允许继承的属性和方法。同时子类也可以添加新的方法或者属性在建立一个新的类层次。
继承的实现与本质?

图2 继承的实现
如图2所示的这个继承体系中,Vehicle为所有交通工具的基类,其定义了所有交通工具都具备的"启动"和"停止"方法。其中Aricraft类实现了IFlyable接口,使得Aricraft可以实现Fly()这一特性。这样的好处是显而易见的,通过IFlyable接口,实现了对象与行为的分离,这样我们就无需担心继承不当而导致Car也拥有了Fly()的能力,保护了系统的稳健性。
public class Vehicle
{
public virtual void Start()
{
Console.WriteLine("Vehicle is Start");
}
public virtual void Stop() {
Console.WriteLine("Vehicle is Stop");
}
}
public class Car: Vehicle {
public override void Start()
{
Console.WriteLine("Car is Start");
}
public override void Stop()
{
Console.WriteLine("Car is Stop");
}
}
public class Aircralt : Vehicle, IFlyable
{
public void Fly()
{
Console.WriteLine("Aircralt is Fly");
}
}
public interface IFlyable {
void Fly();
}
static void Main(string[] args)
{
Vehicle car = new Car();
car.Start();
Console.ReadLine();
}
代码演示
我们来简单分析一下对象的创建过程:
Vehicle car = new Car();
Vehicle car是创建一个Vihicle类型的引用,而new Car()则是创建一个Car对象,分配内存空间和初始化操作,然后将这个对象的引用赋给car变量,也就是建立car变量和Car对象的关联。我们从继承的角度来分析CLR在运行时如何执行对象的创建过程的。我们以car为例,car对象一经建立,首先会利用递归查找到其父类,并为父类分配存储空间。对象的创建过程是按照顺序完成了对整个父类以及本身字段的内存创建。并且字段的存储顺序是由上到下的排列,最高层地的排在上。其原因是如果父类和子类出现了同名的属性,编辑器会自动认为这是两个不同的字段而加以区别。然后是方法表的创建,需要注意一点的是方发表的创建在是类第一次加载到AppDomain是完成的。在创建对象的时候只是讲对象的TypeHandle指向方发表的Loader Heap上,也就是说,方法表是在先于对象创建存在的。类似于字段的创建过程,方法表的创建也是先父类后子类的。在创建子类方法表的时候会先从其最高级别的父类向下递归。首先把父类的所有的虚方法Copy一份,然后和子类方法表做对比,如果有重写操作则以子类的方法覆盖父类的方法。同时添加父类的非虚方法,从而完成car方法表的创建。
从我们的分析和上面创建对象的过程中,我们对继承应有了以下更明确的认识:
- 继承是可以传递的,子类是对父类的扩展,必须继承父类方法,同时可以添加新方法。
- 子类可以调用父类的方法和字段,但是!父类不能调用子类的方法和字段。
- 子类不光继承父类的共有成员,同时也继承了父类的私有成员,只是在子类中访问不到。(不知道可否通过反射访问到。。。。希望可以一起探讨这个问题。)
继承的分类与规则?
继承的分类可以分为两种:实现继承与接口继承
实现继承与接口继承的区别:
抽象类适合于有族层概念的类间关系,而接口最适合为不同的类提供通用功能
接口着重于CAN-DO关系类型,而抽象类则偏重于IS-A式的关系
接口多定义对象的行为;抽象类多定义对象的属性
版本式的问题最好以抽象类来实现
因为值类型是密封的,所以只能实现接口,而不能继承类
好晚了,明天还要上班,,,不写了,未完待续。。。
【.Net基础拾遗】品味OO继承的更多相关文章
- Java基础拾遗(二)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76358523冷血之心的博客) 马上就要秋招了,新的一轮笔试面试马上 ...
- Java基础拾遗(一)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76358391冷血之心的博客) 马上就要秋招了,新的一轮笔试面试马上 ...
- C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点
C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点 第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它 ...
- Python 面向对象之五 基础拾遗
Python 面向对象之五 基础拾遗 今天呢,就剩下的面向对象的相关知识进行学习,主要会学习以下几个方面的知识:1.上下文管理协议,2.为类加装饰器 3.元类 一.上下文管理协议 在学习文件操作的时候 ...
- 基础拾遗------redis详解
基础拾遗 基础拾遗------特性详解 基础拾遗------webservice详解 基础拾遗------redis详解 基础拾遗------反射详解 基础拾遗------委托详解 基础拾遗----- ...
- 基础拾遗------webservice详解
基础拾遗 基础拾遗------特性详解 基础拾遗------webservice详解 基础拾遗------redis详解 基础拾遗------反射详解 基础拾遗------委托详解 基础拾遗----- ...
- 基础拾遗-----mongoDB操作
基础拾遗 基础拾遗------特性详解 基础拾遗------webservice详解 基础拾遗------redis详解 基础拾遗------反射详解 基础拾遗------委托详解 基础拾遗----- ...
- 基础拾遗----RabbitMQ(含封装类库源码)
基础拾遗 基础拾遗------特性详解 基础拾遗------webservice详解 基础拾遗------redis详解 基础拾遗------反射详解 基础拾遗------委托详解 基础拾遗----- ...
- Java12-java语法基础(十一)继承
Java12-java语法基础(十一)继承 一.继承 学习要求: 1. 理解继承的概念与作用 2. 掌握继承的实现机制 3.理解继承中的覆写与覆盖 4.掌握super关键字的使用 回顾: 1.对客观世 ...
随机推荐
- Jacob
http://www.cnblogs.com/luckyxiaoxuan/archive/2012/06/13/2548331.html http://blog.csdn.net/qingwangyo ...
- Hibernate 知识提高
主键生成策略有: UUID,increment.Hilo.assigned:对数据库无依赖 identity:依赖Mysql或sql server,主键值不由hibernate维护 sequence: ...
- hdoj 5311 Hidden String(KMP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5311 思路分析:该问题要求在字符串中是否存在三个不相交的子串s[l1..r1], s[l2..r2], ...
- qt example
#include"mainwindow.h" #include"ui_mainwindow.h" #include<QWebFrame> #incl ...
- HDU 2527
题目描述 HDU 2527 分析 霍夫曼编码的应用. 本题没有必要构造一棵完整的霍夫曼树.只需利用霍夫曼编码的原理,每次挑选频率最低的两个元素进行合并 ...
- 阵列中条带(stripe)、stripe unit
摘抄:http://blog.sina.com.cn/s/blog_4a362d610100aed2.html 在磁盘阵列中,数据是以条带(stripe)的方式贯穿在磁盘阵列所有硬盘中的.这种数据的分 ...
- Oracle存储过程Procedure语法及案例
create or replace procedure replace(desstr in varchar2, replacestr in varchar2, tablename in varchar ...
- mysql 表及其列字符集设置
--修改表的字符集 alter table rtb_media_daily_report character set gbk; --查询表列字符集 show full columns from rtb ...
- jQuery的扩展
我们自己通过扩展jQuery来达到 “通过$.xx(paras)的形式来进行调用某个jQuery对象的xx(paras)方法”. 下面就是一个实例: (function(j){//这里的j是一个形参, ...
- 让正则表达式变简单(PythonVerbalExpressions)
一.安装pip install VerbalExpressions二.导入from verbalexpressions import VerEx三.示例 使用案例一: 测试URL是否有效 from v ...