版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、本讲内容,主要内容 虚方法与方法覆写 虚拟方法表(VMT) 继承与方法覆写的本质 多态的本质 重点 虚方法与方法覆写 虚方法与多态的本质 难点 虚方法与多态的本质,一、虚方法与方法覆写,型与值的问题,型与值通常保持一致 “多态”时,型与值似乎发生了背离,public static void Main() Car c = new Volvo(); DriveCar(c); static void DriveCar(Car c) c.Drive(); ,int a = 10; string s = “Hello, World”;,Driving Volvo 请按任意键继续. . .,开的究竟是什么
2、?,值:Volvo,型:Car,开拖拉机与开汽车的故事,几年前,一个朋友花钱买了个驾照。拿到了驾照的他始终不敢开车,甚至自己买车后也是老婆开车他坐车,所以时常遭到取笑。 一次,这位买驾照的朋友吹嘘说,开车有什么难的,我过去在生产队开过拖拉机,想必和开车差不了多少。“别吹牛,有本事你开一个”有人站出来和叫板。没想到他找了辆车,真的晃晃悠悠开了一圈。当他从车上下来时,所有人都瞪大了眼睛,问他是怎么做到的。尽管脸色有点苍白,他还是忘不了吹牛:“这有什么难的,我全当是在开拖拉机罢了!”。,开拖拉机与开汽车的故事(续),问: 这位买驾照的朋友为什么能把车开走? 他开走的是车还是拖拉机? 这位朋友的逻辑:
3、 汽车 is a kind of 拖拉机 Drive 汽车 as 拖拉机 结果:汽车被开走,Tractor t = new Car(); t.Drive();,验证一下,结论 方法名由父类决定 方法的实现由子类决定,public static void Main() Car c = new Volvo(); DriveCar(c); static void DriveCar(Car c) Console.WriteLine(c.GetType(); c.Drive(); ,Volvo Driving Volvo 请按任意键继续. . .,“不变应万变”的幕后英雄,是什么确保了“多态”效应? 继
4、承 李氏代换:子类可以替换掉父类 虚方法、覆写 父类中定义的虚方法被子类覆写掉了 注意:非虚方法不可以被覆写 问题提出 什么是“覆写”? “虚方法”与“非虚方法”有什么区别?,从“继承”说起,“继承”告诉我们 凡是父类有的子类一定有 如何保障这一点呢? 方法表(Method Table),Method1()实现地址,Method2()实现地址,Method3()实现地址,某类的方法表,Method1的具体实现,Method2的具体实现,Method3的具体实现,using System; public class Base public virtual void SayHello() Cons
5、ole.WriteLine(Hello!); public class Derived : Base public class Client public static void Main() Derived d = new Derived(); d.SayHello(); ,SayHello()地址,Base的方法表,Base类SayHello方法的具体实现代码,SayHello()地址,Derived的方法表,子类没有覆写父类SayHello方法,因此默认使用父类的SayHello方法,确保可以被子类覆写,using System; public class Base public vir
6、tual void SayHello() Console.WriteLine(Hello!); public class Derived : Base public override void SayHello() Console.WriteLine(“New Hello!); ,SayHello()地址,Base的方法表,Base类SayHello方法的具体实现代码,Derived的方法表,确保可以被子类覆写,SayHello()地址,Derived类SayHello方法的具体实现代码,子类覆写了父类SayHello方法,因此使用覆写后的SayHello方法,public class Veh
7、icle public virtual void Drive(); public class Car : Vehicle public class Truck : Car ,Drive()地址,Vehicle的方法表,Vehicle类Drive方法的具体实现代码,Car的方法表,Drive()地址,Truck的方法表,Drive()地址,Truck类Drive方法的具体实现代码,public override void Drive();,Vehicle,Car,Truck,public override void Drive();,Car类Drive方法的具体实现代码,二、虚拟方法表,什么是虚
8、拟方法表,多个实例共享一个VMT,但各自存储自己的属性,堆,VMT,堆栈,00A0,Drive()的具体实现,Stop()的具体实现,a1,public class Vehicle public int wheels; public int speed; public virtual void Drive() public virtual void Stop() ,00B0,a2,虚拟方法表特点,子类与父类中相同的方法与属性在各自的虚拟方法表中具有相同的偏移量。 后面我们只考虑方法部分,public class Vehicle public int wheels; public int spe
9、ed; public virtual void Drive() public virtual void Stop() ,public class Car : Vehicle public int maxSpeed; public override void Drive() public virtual void SetMaxSpeed() ,0,1,2,3,-1,-2,-3,三、继承与方法覆写的本质,继承案例分析,继承 父类有,子类一定有 子类继承了属性、方法等 父类在哪,子类也在哪 在虚拟方法表中的相对位置相同,using System; public class Vehicle publi
10、c int wheels; public int speed; public virtual void Drive() Console.WriteLine(Drive Vehicle.); public virtual void Stop() Console.WriteLine(Stop Vehicle.); public class Motorcycle : Vehicle public override void Drive() Console.WriteLine(Drive Motorcycle.); public override void Stop() Console.WriteLi
11、ne(Stop Motorcycle.); public class Car : Vehicle public int maxSpeed; public override void Drive() Console.WriteLine(Drive Car.); public virtual void SetMaxSpeed(int maxSpeed) this.maxSpeed = maxSpeed; Console.WriteLine(Set car max speed to 0., maxSpeed); ,public class PassengerCar : Car public int
12、maxPassengers; public void SetMaxPassengers(int maxPassengers) this.maxPassengers = maxPassengers; Console.WriteLine(Set max passengers to 0., maxPassengers); public class Truck : Car public int carryingCapacity; public override void Stop() Console.WriteLine(Stop Truck.); public void SetCarryingCapa
13、city(int carryingCapacity) this.carryingCapacity = carryingCapacity; Console.WriteLine(Set carrying capacity to 0t., carryingCapacity); ,继承关系的代码描述,Vehicle.Drive,Vehicle.Stop,Motorcycle.Drive,Motorcycle.Stop,Car.Drive,Car.SetMaxSpeed,PassengerCar.SetMaxPassengers,Truck.Stop,Truck.SetCarryingCapacity,
14、方法的覆写(override),四、多态的本质,多态,多态的特点 方法名由父类决定 方法的实现由子类决定,public class Client public static void Main() Vehicle v = new Truck(); v.Drive(); ,Truck的Drive方法被调用,为什么?,Vehicle.Drive,Vehicle.Stop,Motorcycle.Drive,Motorcycle.Stop,Car.Drive,Car.SetMaxSpeed,PassengerCar.SetMaxPassengers,Truck.Stop,Truck.SetCarryi
15、ngCapacity,堆,堆栈,00A0,v,Vehicle v = new Truck();,v.Drive();,v.Stop();,v.GetType();,对比: Truck v = new Truck(); 执行结果完全一样!,虚方法的本质,虚方法v.Drive()的调用本质 (* v.VMTidx)(v); idx 是 Drive 方法在 VMT 中的偏移量 调用参数中的 v 是隐含传递的 this 指针 型是设计时,值是运行时 idx 取决于型,在编译时就被确定 v 是由运行时具体的对象类型决定的,public static void Main() Drive(new Truck
16、(); Drive(new Car(); static void Drive(Vehicle v) v.Drive(); ,public static void Main() Drive(new Truck(); Drive(new Car(); static void Drive(Vehicle v) (* v.VMTidx)(v); ,idx 在编译时确定: 型是 Vehicle,Vehicle 的 Drive方法的偏移量为 1,public static void Main() Drive(new Truck(); Drive(new Car(); static void Drive(V
17、ehicle v) (* v.VMT1)(v); ,传入new Truck()时: (*VMT_of_Truck1)(v); 传入new Car()时: (*VMT_of_Car1)(v); 实现了“以不变应万变”,方法小结,方法,静态方法,非静态方法,非虚的实例方法,虚的实例方法,Static Method,virtual override,none virtual,Instance Method,MethodName(class, parameters);,MethodName(this, parameters);,(* obj.VMTidx)(this, parameters);,强制类
18、型转换,转换原则 子类可以隐式转换成父类 父类必须显式转换成子类,Truck t = new Truck(); Vehicle v = t;,Vehicle v = new Truck(); Truck t = (Truck)v;,Vehicle.Drive,Vehicle.Stop,Motorcycle.Drive,Motorcycle.Stop,Car.Drive,Car.SetMaxSpeed,PassengerCar.SetMaxPassengers,Truck.Stop,Truck.SetCarryingCapacity,堆,堆栈,00A0,v,Vehicle v = new Tru
19、ck();,v.GetType();,Truck t = (Truck)v;,t.GetType();,00A0,t,使用new关键字隐藏方法,class Token . public int LineNumber( ) . class CommentToken: Token . new public int LineNumber( ) . ,使用new关键字隐藏方法(续),可以隐藏“虚”与“非虚”方法 将具有相同“方法签名”的方法隐藏起来,class Token . public int LineNumber( ) . public virtual string Name( ) . clas
20、s CommentToken: Token . new public int LineNumber( ) . public override string Name( ) . ,作业:写出下面程序运行结果,class A public virtual void M() Console.Write(A); class B: A public override void M() Console.Write(B); class C: B new public virtual void M() Console.Write(C); class D: C public override void M() Console.Write(D); static void Main() D d = new D(); C c = d; B b = c; A a = b; d.M(); c.M(); b.M(); a.M(); ,五、应用举例,以不变应万变中的“马脚”,马脚所在 new 出来的对象是什么,行为就是什么 怎么能说是“不变”呢?,public
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- SMTP服务器租赁合同范本
- 教育设施爱心基金管理办法
- 能源企业隔音墙施工合同
- 人工智能项目投资担保人还款协议
- 教育咨询高级顾问聘用合同样本
- 旅游设施施工合同备案说明
- 园林绿化施工管理合同样本
- 教育公益捐赠管理办法
- 环保设施清洁施工合同建筑膜
- 体育馆化粪池建设协议
- 装载机零件目录(以徐工lw500kn为例)
- 行政事业单位经济责任审计报告范文
- 泵盖铸造工艺课程设计
- 无损检测Ⅱ级人员超声(UT)锻件门类专业知识试题及详解
- 销售大户监管办法
- 小型装配式冷库设计(全套图纸)
- 电动汽车无线充电技术
- 审计工作手册
- 防蛇安全教育培训
- 胰腺癌一病一品知识分享
- 【原创】《基于地理实践力培养的校本课程开发研究》中期报告
评论
0/150
提交评论