简易Java(16):Java中的覆盖和重载
1、定义
对于Java初学者来说,覆盖(Overriding)和重载(Overloading)是两个非常容易混淆的概念。
重载的情况是这样的,在同一个类中,有两个甚至更多的方面,他们名称相同,但是有不同的参数列表。
覆盖的意思是,有两个同名的方法,同时还有相同的参数列表,但是却有不同的实现。其中一个存在于父类中,另外一个在子类中。
2、覆盖 vs 重载
对于覆盖和重载有几个非常重要的事实需要注意:
- 真实的对象类型,而不是引用变量的类型,至于哪个覆盖方法会被使用是在运行时决定的;
- 引用类型在编译时决定那个重载方法被使用;
- 多态性取决于覆盖,而不是重载。
3、覆盖示例
这里有一个覆盖的示例。阅读代码,然后猜测将要输出什么?
package com.diguage.books.simplejava.ar16.v1; /** * 覆盖示例一:父类 * <p/> * Coder:D瓜哥,http://www.diguage.com/ * <p/> * Date: 2014-11-16 10:08 */ public class Dog { public void bark() { System.out.println("woof "); } }
package com.diguage.books.simplejava.ar16.v1; /** * 覆盖示例一:子类 * <p/> * Coder:D瓜哥,http://www.diguage.com/ * <p/> * Date: 2014-11-16 10:12 */ public class Hound extends Dog { public void sniff() { System.out.println("sniff "); } @Override public void bark() { System.out.println("bowl"); } }
package com.diguage.books.simplejava.ar16.v1; /** * 覆盖示例一:Main类 * <p/> * Coder:D瓜哥,http://www.diguage.com/ * <p/> * Date: 2014-11-16 10:15 */ public class OverridingMain { public static void main(String[] args) { new Hound().bark(); ((Dog) new Hound()).bark(); // ((Dog)new Hound()).sniff(); } }
输出如下,你猜对了吗?
bowl bowl
一个更好的例子:
package com.diguage.books.simplejava.ar16.v2; /** * 覆盖示例二:父类Animal * <p/> * Coder:D瓜哥,http://www.diguage.com/ * <p/> * Date: 2014-11-16 10:19 */ public class Animal { public void stinky() { System.out.println("stinky animal !"); } }
package com.diguage.books.simplejava.ar16.v2; /** * 覆盖示例二:子类Cow * <p/> * Coder:D瓜哥,http://www.diguage.com/ * <p/> * Date: 2014-11-16 10:22 */ public class Cow extends Animal { @Override public void stinky() { System.out.println("stinky cow !"); } }
package com.diguage.books.simplejava.ar16.v2; /** * 覆盖示例二:子类Dog * <p/> * Coder:D瓜哥,http://www.diguage.com/ * <p/> * Date: 2014-11-16 10:20 */ public class Dog extends Animal { @Override public void stinky() { System.out.println("stinky dog !"); } public void bark() { System.out.println("wow wow!"); } }
package com.diguage.books.simplejava.ar16.v2; /** * 覆盖示例二:Main类 * <p/> * Coder:D瓜哥,http://www.diguage.com/ * <p/> * Date: 2014-11-16 10:23 */ public class Main { public static void main(String[] args) { Animal obj = new Dog(); obj.stinky(); } }
当你像上面那样创建对象并调用方法时:
Animal obj = new Dog(); obj.stinky();
编译器要做的就是检查对象类型,对于这个例子就是Animal
。然后检查在Animal
中是否定义stinky()
方法。请注意,在运行时才创建对象。所以,编译器不知道Dog
的stinky()
方法是否被调用。所以,在编译时,引用变量的类型被用于检查一个方法是否存在。
在运行时,Java虚拟机知道,虽然对象的类型是Animal
,但是在运行时对象引用指向一个Dog
实例。所以,调用Dog
的stinky()
方法。这就是动态多态性。
《Simple Java》是一本讲解Java面试题的书。讲解也有不少独特之处,为了面试,《简易Java》走起!
作 者: D瓜哥,https://www.diguage.com/
原文链接:https://wordpress.diguage.com/archives/123.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
原文链接:https://wordpress.diguage.com/archives/123.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。