首页 > Java, 挨踢(IT) > 简易Java(16):Java中的覆盖和重载

简易Java(16):Java中的覆盖和重载

2014年11月16日 发表评论 阅读评论 298 人阅读    

1、定义

对于Java初学者来说,覆盖(Overriding)和重载(Overloading)是两个非常容易混淆的概念。

重载的情况是这样的,在同一个类中,有两个甚至更多的方面,他们名称相同,但是有不同的参数列表。

覆盖的意思是,有两个同名的方法,同时还有相同的参数列表,但是却有不同的实现。其中一个存在于父类中,另外一个在子类中。

2、覆盖 vs 重载

对于覆盖和重载有几个非常重要的事实需要注意:

  1. 真实的对象类型,而不是引用变量的类型,至于哪个覆盖方法会被使用是在运行时决定的;
  2. 引用类型在编译时决定那个重载方法被使用;
  3. 多态性取决于覆盖,而不是重载。

3、覆盖示例

这里有一个覆盖的示例。阅读代码,然后猜测将要输出什么?

01package com.diguage.books.simplejava.ar16.v1;
02 
03/**
04 * 覆盖示例一:父类
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-16 10:08
09 */
10public class Dog {
11    public void bark() {
12        System.out.println("woof ");
13    }
14}
01package com.diguage.books.simplejava.ar16.v1;
02 
03/**
04 * 覆盖示例一:子类
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-16 10:12
09 */
10public class Hound extends Dog {
11    public void sniff() {
12        System.out.println("sniff ");
13    }
14 
15    @Override
16    public void bark() {
17        System.out.println("bowl");
18    }
19}
01package com.diguage.books.simplejava.ar16.v1;
02 
03/**
04 * 覆盖示例一:Main类
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-16 10:15
09 */
10public class OverridingMain {
11    public static void main(String[] args) {
12        new Hound().bark();
13        ((Dog) new Hound()).bark();
14//        ((Dog)new Hound()).sniff();
15    }
16}

输出如下,你猜对了吗?

一个更好的例子:

01package com.diguage.books.simplejava.ar16.v2;
02 
03/**
04 * 覆盖示例二:父类Animal
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-16 10:19
09 */
10public class Animal {
11    public void stinky() {
12        System.out.println("stinky animal !");
13    }
14}
01package com.diguage.books.simplejava.ar16.v2;
02 
03/**
04 * 覆盖示例二:子类Cow
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-16 10:22
09 */
10public class Cow extends Animal {
11    @Override
12    public void stinky() {
13        System.out.println("stinky cow !");
14    }
15}
01package com.diguage.books.simplejava.ar16.v2;
02 
03/**
04 * 覆盖示例二:子类Dog
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-16 10:20
09 */
10public class Dog extends Animal {
11 
12    @Override
13    public void stinky() {
14        System.out.println("stinky dog !");
15    }
16 
17    public void bark() {
18        System.out.println("wow wow!");
19    }
20}
01package com.diguage.books.simplejava.ar16.v2;
02 
03/**
04 * 覆盖示例二:Main类
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-16 10:23
09 */
10public class Main {
11    public static void main(String[] args) {
12        Animal obj = new Dog();
13        obj.stinky();
14    }
15}

当你像上面那样创建对象并调用方法时:

1Animal obj = new Dog();
2obj.stinky();

编译器要做的就是检查对象类型,对于这个例子就是Animal。然后检查在Animal中是否定义stinky()方法。请注意,在运行时才创建对象。所以,编译器不知道Dogstinky()方法是否被调用。所以,在编译时,引用变量的类型被用于检查一个方法是否存在。

在运行时,Java虚拟机知道,虽然对象的类型是Animal,但是在运行时对象引用指向一个Dog实例。所以,调用Dogstinky()方法。这就是动态多态性。

《Simple Java》是一本讲解Java面试题的书。讲解也有不少独特之处,为了面试,《简易Java》走起!



作 者: D瓜哥,https://www.diguage.com/
原文链接:https://wordpress.diguage.com/archives/123.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

分类: Java, 挨踢(IT) 标签: ,
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.