【.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.对客观世 ...
随机推荐
- Qt 智能指针学习(7种QT的特有指针)
从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int arg ...
- Qt中QPushButton、QTabWidget等部件内容文字换行的解决方法(一定要写在源码里,写在翻译文件里不行,因为\n得不到转义)
最近在做基于Qt的应用项目,其中有一个按钮文字超长,需要换一行显示.从网上找到的建议都是将要显示的内容做成图片,然后将图片设置为该按钮的背景.但是这样做有一个很大的局限性,当需要更改内容文字的时候,需 ...
- 使用回调接口实现ActiveX控件和它的容器程序的通讯
本文阅读基础:有一定的C++基础知识(了解继承.回调函数),对MFC的消息机制有一定了解,对COM的基础知识有一定了解,对ActiveX控件有一定了解. 一. 前言 ActiveX控件和它的容器程序如 ...
- Balanced Binary Tree --Leetcode C++
递归 左子树是否为平衡二叉树 右子树是否为平衡二叉树 左右子树高度差是否大于1,大于1,返回false 否则判断左右子树 最简单的理解方法就是如下的思路: class Solution { publi ...
- AndroidStudio项目移植到Eclipse
原文件结构: 在AndroidStudio中 main目录对应eclipse中的src目录 可以看看每个文件夹下的目录 没有src或者main这些文件夹的都可以删掉 我这里只有app下的东西是需要留着 ...
- iphone开发小记
程序功能:点击Button实现按钮的文本变换 一,打开Xcode,新建single view based application,拖动一个Button控件到屏幕中间 项目目录树下包含AppDelega ...
- Color the ball(树状数组+线段树+二分)
Color the ball Time Limit : 9000/3000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Tota ...
- [BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘
[Problem Description] 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队 ...
- 利用Linux命令行进行文本按行去重并按重复次数排序
最近杂事太多,正事进展缓慢.Fighting! linux命令行提供了非常强大的文本处理功能,组合利用linux命令能实现好多强大的功能.本文这里举例说明如何利用Linux命令行进行文本按行去重并按重 ...
- sass基本语法
sass是一种基于ruby语言开发的CSS预处理器.它可以使用变量,嵌套,混入,继承,运算,函数等编程语言具有的特性进行CSS的开发,使得CSS的开发变得简单粗暴清晰可维护. sass有两种后缀文件格 ...