知识大全 从实例中看多态
Posted 函数
篇首语:人喜欢习惯,因为造它的就是自己。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 从实例中看多态相关的知识,希望对你有一定的参考价值。
近来看了一下多态性 把我的一些感受以例子的形式记录一下 一 形象理解 两条理解的原则 ( )一个派生类对象可以被声明成一个基类 或者是一个基类指针可以指向一个派生类对象 //c++ code BaseClass *p; DerivedClass obj; p = &obj; //C# code BaseClass obj = new DerivedClass() ( )把一个对象看做是一个独立的个体 调用对象的public成员函数实际上是给这个对象发送一个消息 采取什么样的动作完全由对象自己决定 Shape是基类 Circle和Line是从Shape继承出来的 Shape有draw()方法 Circle与Line分别自己定义了自己的draw()方法 在下面的代码里 // Java Code static void func(Shape s) s Draw() 如果发生了这样的调用 Line l = new Line() Circle c = new Circle() func(l) func( c) 一个Circle和一个Line被当做Shape传到函数里去了 然后调用Draw() 会发生什么情况?因为对象是独立的个体 在func()里 这两个对象被分别传递了Draw()消息 叫它们绘制自己吧 于是他们分别调用了自己类里定义的Draw()动作 通过这两条原则我们可以理解上面的多态 正是由于多态 使得我们不必要这样去做 IF 你是一个Circle THEN 调用Circle的Draw() ELSE IF 你是一个Line THEN 调用Line的Draw() ELSE … 我们只要给这个被声明成为Shape的对象发送Draw消息 怎么样去Draw就由对象自己去决定了 二 一切皆因虚函数 先看看实现多态的基本条件 ( ) 基类含有虚函数 ( ) 继承类把这个虚函数重新实现了 ( ) 继承类也可能没有重新实现基类的所有虚函数 因此对于这些没有被重新实现的虚函数不能发生多态 再看一下几种语言里一些特别的规定 C++ ( )虚函数用virtual关键字声明 ( )virtual void Func(para_list) = ;这样的虚函数叫做纯虚函数 表示这个函数没有具体实现 包含纯虚函数的类叫做抽象类 如果他的继承类没有对这个纯虚函数具体用代码实现 则这个继承类也是抽象类 抽象类不能被实例话(就是说不能创建出对象) ( )继承类重新实现基类的虚函数时 不需要做任何特别的声明 ( )如果不用virtual关键字修饰 并且在派生类里重新实现了这个方法 这仅仅是一个简单的覆蓋 不会发生多态 我们暂称它非多态吧 Java ( )Java没有virtual关键字 Java把一切类的方法都认为是虚函数 ( )继承类重新实现基类的虚函数时 不需要做任何特别的声明 因此在Java里只要重新实现了基类的方法 并且把继承类对象声明为基类 多态就要发生 因此Java对多态的条件相对是比较低的 //Java Code class BaseClass public void hello(); class DerivedClass extends BaseClass public void hello() System out println( Hello world! ) public static void main(String args[]) BaseClass obj = new DerivedClass() obj hello() 输入是Hello world! 这样就实现了多态 ( )虚函数用abstract声明 含有虚函数的类是抽象类 也要用abstract关键字修饰 //Java Code public abstract AbstractClass public abstract void hello() //… C# C#对于多态的编写是最为严格和严谨的 ( )虚函数用virtual声明 ( )纯虚函数用abstract声明 含纯虚函数的类是抽象类 必须用abstract关键字修饰 ( )如果仅仅是覆蓋基类的非虚方法 则需要用new关键字声明 //C# Code public class BaseClass public void hello() System Console WriteLine( Hello this e from BaseClass ) public class DerivedClass : BaseClass public new void hello() System Console WriteLine( Hello this is e from DerivedClass ) public static void Main() BaseClass obj = new DerivedClass() obj hello() 输出为Hello this e from BaseClass 也就是说这并没有实现多态(非多态) ( )通过virtual – override abstract – override组合实现多态 当派生类重新实现基类的虚函数(或纯虚函数)时 必须用override关键字进行修饰 //C# Code public abstract class AbsBaseClass public abstract void hello() public class DerivedClass : AbsBaseClass public void hello() System Console WriteLine( Hello world! ) public static void SayHello(AbsBaseClass obj) obj hello() public static void Main() DerivedClass _obj = new DerivedClass() DerivedClass SayHello(_obj) 输出为Hello world! 三 多态的反溯 继承类对象在发生多态时 并是不完全抛开基类不管的 它会去查看基类的虚函数列表 在这个列表的范围内才会发生多态 让我们来看一个比较复杂的例子 // Java Code class A protected void hello(Object o) System out println( A Object ) class B extends A protected void hello(String s) System out println( B String ) protected void hello(Object o) System out println( B Object ) ; class C public static void main(String args[]) Object obj = new Object() String str = ABC ; A a = new B() a hello(obj) a hello(str) ; 输出结果为 B – Object B – Object 正如上面所说的 由于基类里没有参数类型为String的虚函数 因此B的hello(String)方法不参与多态 调用a hello(str)时 由于String是Object的继承类 因此这个str被作为一个Object传入了B的hello(Object) 这一点正如我们的原则一所述 四 接口——仅仅是更抽象的抽象类 接口是类的协定 但由于接口又参与多态性 从这一点说 我们认为它是更为抽象的抽象类 如下 // Java Code interface IBase void hello() class DerivedClass implements IBase public void hello() System out println( Hello world! ) public static void main(String args[]) IBase obj = new DerivedClass() obj hello() 在Java与C#中 类只能从一个基类派生出来 但是可以实现多个接口 这里有一个小小的问题 如果IBase 与IBase 里都声明了有hello()方法 DerivedClass实现了这两个接口 当然需要具体把hello()实现出来 interface IBase void hello() interface IBase void hello() public class DerivedClass : IBase IBase public void hello() System Console WriteLine( Hello world! ) public class DerivedClass : IBase IBase void IBase hello() System Console WriteLine( This e from IBase ) void IBase hello() System Console WriteLine( This e from IBase ) public static void Main() IBase obj_ = new DerivedClass () IBase obj_ = new DerivedClass () IBase obj_ = new DerivedClass () IBase obj_ = new DerivedClass () obj_ hello() obj_ hello() obj_ hello() obj_ hello() 输出为 Hello world! Hello world!; This e from IBase This e from IBase 有两点注意 ( )DerivedClass 的实现方法叫显式实现 这种方法C#才支持 在Java里不能实现 ( )进一步测试表明 hello()方法并不属于DerivedClass 加入这样的代码 DerivedClass t = new DerivedClass () t hello() 编译错误 test cs( ) error CS : DerivedClass 并不包含对 hello 的定义 那就是说这个方法是属于接口的 但是接口不能含有具体的实现代码 这里是不是存在一定的矛盾呢? cha138/Article/program/net/201311/12588相关参考
多态可以理解为事物存在的多种体现形态 多态的体现 父类的引用指向了自己的子类对象 父类的引用也可以接收自己的子类对象 多态的前提 必须是类与类之间有关系要么继承要么实现 通常还有一个前
浅谈.NET中不一样的多态 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在NET中多态通常意味
Java运行时多态性的实现 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 运行时多态性是面向对象
Java核心Java中多态的实现机制 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 多态性是面向
图文并茂教你如何在Eclipse中看源代码 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! >
在OOP简介:理解类和对象这篇文章中我们讨论了继承和多态性的好处我们还粗略的学习了如何扩展基类定义子类继承基类中合适的行为和属性而重载那些并不适合的行为和属性这种方式能够削减代码宏余以及错误的堆积
(一)相关类 (二)问题以下输出结果是什么? (
JAVA中用接口实现多继承和多态的方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! JAVA里
Java中使用接口实现多继承和多态的方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! JAVA
不管时光如何流逝应该说每个人对他职业生涯的第一次面试都是记忆犹新不是吗? 经过前两轮的筛选我推开那扇门小心翼翼地坐在Andy面前我应聘的职位是C++程序员坦率的讲我有一些紧张您知道的一个找不