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

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

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

1、定义

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

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

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

2、覆盖 vs 重载

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

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

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()方法。请注意,在运行时才创建对象。所以,编译器不知道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.