简易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
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
