关于java多态中覆盖的理解

在前面一篇文章中,我已经介绍了关于java多态中重载的理解与规则

  所以这篇文章主要介绍多态中的覆盖机制。

  首先重载与覆盖除了表现方式不同之外,还有运行时间上的不同,重载是在编译期间就已经可以确定好调用的方法,而覆盖则是在运行期间才能确定。(这是由于覆盖是一般是建立在继承之上的,即需要通过继承链(指针)的查找

  多态覆盖的主要难度表现在:

  对于一个父类变量,引用的是子类对象,那么需要知道父类变量在调用方法时,调用的是谁的方法。

  一、实例方法在运行多态时的表现

  这是父类方法

public class Forefather {
    public void normal() {
        System.out.println("这是父类的普通方法");
    }
}

 

  这是子类方法

public class Inheritor extends Forefather{
    public void normal() {//这里覆盖了父类的同名方法
        System.out.println("这是子类的普通方法");
    }

}

  多态表现

public class ShowStrange {
    public static void main(String args[]) {
        Forefather pfather;//定义一个父类变量
        Inheritor  pson;//定义一个子类变量
        pfather = new Inheritor();//创建子类对象
        pfather.normal();//调用子类方法
//        pson = new Forefather();子类的变量不能创建父类对象
        pson = new Inheritor();
        pson.normal();
    }
}

  运行结果是:

这是子类的普通方法
这是子类的普通方法

这就说明该变量是什么对象时,就调用什么方法,而与声明变量的类无关。

    但是更神奇的在这里:

public class Ancestors {//父类变量
    public void common() {
        System.out.println("这是父类的common方法");
    }
    public void anceshow() {
        common();
    }
}
public class Derive extends Ancestors{//子类变量
    public void common() {//覆盖父类的同名方法
        System.out.println("这是子类的common方法");
    }
    public void deriveShow() {
        anceshow();    
    }
    public static void  main(String args[]) {
        Ancestors oa = new Ancestors();
        oa.anceshow();//执行的是父类的方法
        Derive ob = new Derive();
        ob.deriveShow();//执行的是子类的方法
    }
}

运行结果:

这是父类的common方法
这是子类的common方法

  神奇之处就在于ob.deriveshow执行是调用的父类的anceshow方法,而在执行anceshow方法时并未调用父类的common方法,而是返回到子类中执行子类的common方法,相当于自己出去了一圈又找回来了

补充:

讨论完方法后,你是否对于成员变量是否也具有多态性有疑问?

  这里就不补充源代码了,明确的说,对于成员变量而言无论是实例,静态成员,都没有这一特性,对成员变量的引用在编译时就已经确定好了,即声明的变量为那个类,这个成员变量就属于哪个类。

posted @ 2018-03-16 21:03  沉默的赌徒  阅读(379)  评论(0编辑  收藏  举报