类型、方法与继承

上传人:豆浆 文档编号:47459875 上传时间:2018-07-02 格式:PPT 页数:40 大小:447.50KB
返回 下载 相关 举报
类型、方法与继承_第1页
第1页 / 共40页
类型、方法与继承_第2页
第2页 / 共40页
类型、方法与继承_第3页
第3页 / 共40页
类型、方法与继承_第4页
第4页 / 共40页
类型、方法与继承_第5页
第5页 / 共40页
点击查看更多>>
资源描述

《类型、方法与继承》由会员分享,可在线阅读,更多相关《类型、方法与继承(40页珍藏版)》请在金锄头文库上搜索。

1、类型、方法与继承类型简述 n在.NET代码中,我们可以很方便的创建各种 类型,一个简单的数据模型、复杂的聚合对象 类型、或是对客观世界实体的抽象 。n类 (class) 是最基础的 C# 类型 ,支持继承与 多态。一个c# 类Class主要包含两种基本成员 : n状态(字段、常量、属性等)n操作(方法、事件、索引器、构造函数等)n利用创建的类型(或者系统提供的),可以很 容易的创建对象的实例。使用 new 运算符创 建,该运算符为新的实例分配内存,调用构造 函数初始化该实例,并返回对该实例的引用, 如下面的语法形式: n = new (构造函数的 参数) n创建后的实例对象,是一个存储在内存上

2、(在 线程栈或托管堆上)的一个对象 ,可以创造 实例的类型在内存中又是一个什么样的存在 ?Type Objectn就是类型对象(Type Object) nint a = 123; / 创建int类型实例a nint b = 20; / 创建int类型实例b nvar atype = a.GetType(); / 获取对象实例a的类型nType var btype = b.GetType(); / 获取对象实例b的类 型Type nConsole.WriteLine(System.Object.Equals(atype,btyp e); /输出:True nConsole.WriteLine(

3、System.Object.ReferenceEquals( atype, btype); /输出:True n任何对象都有一个GetType()方法(基类 System.Object提供的),该方法返回一个对 象的类型,类型上面包含了对象内部的详细信 息,如字段、属性、方法、基类、事件等等( 通过反射可以获取)。在上面的代码中两个不 同的int变量的类型(int.GetType())是同一个 Type,说明int在内存中有唯一一个(类似静 态的)Systen.Int32类型。 n上面获取到的Type对象(Systen.Int32)就是 一个类型对象,她同其他引用类型一样,也是 一个引用对象,

4、这个对象中存储了int32类型的 所有信息(类型的所有元数据信息)。 n每一个类型(如System.Int32)在内存中都 会有一个唯一的类型对象,通过(int) a.GetType()可以获取该对象; n类型对象(Object Type)存储在内存中一个 独立的区域,叫加载堆(Load Heap),加载 堆是在进程创建的时候创建的,不受GC垃圾 回收管制,因此类型对象一经创建就不会被释 放的,他的生命周期从AppDomain创建到结束 ; n前问说过,每个引用对象都包含两个附加成 员:TypeHandle和同步索引块,其中 TypeHandle就指向该对象对应的类型对象;n类型对象的加载由c

5、lass loader负责,在第一 次使用前加载;n类型中的静态字段就是存储在这里的(加载 堆上的类型对象),所以说静态字段是全局的 ,而且不会释放;方法表n类型对象内部的主要的结构是怎么样的呢?其 中最重要的就是方法表,包含了是类型内部的 所有方法入口。npublic class A public virtual void Print() Console.WriteLine(“A“); npublic class B1 : A public override void Print() Console.WriteLine(“B1“); npublic class B2 : A public n

6、ew void Print() Console.WriteLine(“B2“); nB1 b1 = new B1(); B2 b2 = new B2(); n内部结构图方法表的加载 n方法表的加载时父类在前子类在后的,首先加 载的是固定的4个来自System.Object的虚方法 :ToString, Equals, GetHashCode, and Finalize;n然后加载父类A的虚方法;n加载自己的方法;n最后是构造方法:静态构造函数.cctor(),对象 构造函数.ctor()n方法的调用:当执行代码b1.Print()时(此处只 关注方法调用,忽略方法的继承等因素),通 过b1的T

7、ypeHandel找到对应类型对象,然后 找到方法表槽,然后是对应的IL代码,第一次 执行的时候,JIT编译器需要把IL代码编译为 本地机器码,第一次执行完成后机器码会保留 ,下一次执行就不需要JIT编译了。这也是为 什么说.NET程序启动需要预热的原因。 继承本质n方法表的创建过程是从父类到子类自上而下的 ,这是.NET中继承的很好体现,当发现有覆 写父类虚方法会覆盖同名的父方法,所有类型 的加载都会递归到System.Object类 。n继承是可传递的,子类是对父类的扩展,必须 继承父类方法,同时可以添加新方法。n子类可以调用父类方法和字段,而父类不能调 用子类方法和字段。 n子类不光继承

8、父类的公有成员,也继承了私有 成员,只是不可直接访问。nnew关键字在虚方法继承中的阻断作用,中断 某一虚方法的继承传递。n因此类型B1、B2的类型对象进一步的结构示意图如 下:n在加载B1类型对象时,当加载override B1.Print(“B1”) 时,发现有覆写override的方法,会覆盖父类的同名 虚方法Print(“A”),就是下面的示意图,简单来说就是 在B1中Print只有一个实现版本;n加载B2类型对象时,new关键字表示要隐藏基类的虚 方法,此时B2中的Print(“B2”)就不是虚方法了,她是 B2中的新方法了,简单来说就是在B2类型对象中 Print有2个实现版本;n

9、B2 b2 = new B2(); B1 b1 = new B1(); n b1.Print(); b2.Print(); /按预期应该输出 B1、 B2 nA ab1 = new B1(); A ab2 = new B2();ab1.Print(); ab2.Print(); /这里应该输出什么呢 ? 用基类(A)和用本身B1声明到底有什么区别: n无论用什么做引用声明,哪怕是object,等号右边的 = new 类型()都是没有区别的,也就说说对象的创建 不受影响的,b1和ab1对象在内存结构上是一致的;n他们的的差别就在引用指针的类型不同,这种不同在 编码中智能提示就直观的反应出来了,在

10、实际方法调 用上也与引用指针类型有直接关系;n综合来说,不同引用指针类型对于对象的创建(new 操作)不影响;但对于对象的使用(如方法调用)有 影响,这一点在上面代码的执行结果中体现出来了!n对于虚方法的调用,在IL中都是使用指令 callvirt,该指令主要意思就是具体的方法在运 行时动态确定的: ncallvirt使用虚拟调度,也就是根据引用类型的 动态类型来调度方法,callvirt指令根据引用变 量指向的对象类型来调用方法,在运行时动态 绑定,主要用于调用虚方法。 n不同的类型指针在虚拟方法表中有不同的附加 信息作为标志来区别其访问的地址区域,称为 offset。不同类型的指针只能在其

11、特定地址区 域内进行执行。编译器在方法调用时还有一个 原则: n执行就近原则:对于同名字段或者方法,编译 器是按照其顺序查找来引用的,也就是首先访 问离它创建最近的字段或者方法。 nA ab1 = new B1();A ab2 = new B2(); ab1.Print(); ab2.Print(); /这里应该输出什么呢 ? n当执行以下代码时,引用指针类型都为父类A ,引用指针类型的offset指向父类,如下图, 按照就近查找执行原则,输出B1、A 继承n抽象类:n抽象类提供多个派生类共享基类的公共定义, 它既可以提供抽象方法,也可以提供非抽象方 法。抽象类不能实例化,必须通过继承由派生

12、类实现其抽象方法,因此对抽象类不能使用 new关键字,也不能被密封。 n抽象类使用Abstract声明,抽象方法也是用 Abstract标示;n抽象类不能被实例化;n抽象方法必须定义在抽象类中;n抽象类可以继承一个抽象类;n抽象类不能被密封(不能使用sealed);n同类Class一样,只支持单继承;npublic abstract class AbstractUser public int Age get; set; public abstract void SetName(string name); 接口n接口简单理解就是一种规范、契约,使得实现 接口的类或结构在形式上保持一致。实现接口

13、的类或结构必须实现接口定义中所有接口成员 ,以及该接口从其他接口中继承的所有接口成 员。 基本特点:n接口使用interface声明;n接口类似于抽象基类,不能直接实例化接口;n接口中的方法都是抽象方法,不能有实现代码,实现 接口的任何非抽象类型都必须实现接口的所有成员:n接口成员是自动公开的,且不能包含任何访问修饰符 。n接口自身可从多个接口继承,类和结构可继承多个接 口,但接口不能继承类。在.NET中继承的主要两种方式就是类继承和接 口继承,两者的主要思想是不一样的:n类继承强调父子关系,是一个“IS A”的关系, 因此只能单继承(就像一个人只能有一个 Father);n接口继承强调的是一种规范、约束,是一个 “CAN DO”的关系,支持多继承,是实现多态 一种重要方式。n更准确的说,类可以叫继承,接口叫“实现”更 合适。nCONST STATIC READONLY

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文 > 毕业论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号