Java-虚方法

138 阅读2分钟

1、虚方法:
凡是可以被子类重写的方法,都叫做虚方法。
子类不能重写的方法就不是虚方法。
不能重写的方法有:private等(后面还会学习static等)

2、虚方法的调用原则
(1)编译时:看父类
在父类中找到能够匹配的方法
(2)运行时:看子类
如果子类重写了这个匹配的虚方法,那么一定执行重写的方法,
如果子类没有重写这个匹配的虚方法,还是执行父类中找到的这个方法。如果父类中也没有,则去找能够兼容的进行匹配

public class TestVirtualMethod {
    public static void main(String[] args) {
        MyClass my = new MySub();
        Father f = new Father();
        Son s = new Son();
        Daughter d = new Daughter();
        
        my.method(f);//sub--father
        /*
        my变量的编译时类型是MyClass,编译时看MyClass,
        my变量的运行时类型是MySub,运行时看MySub
        (1)第一步,编译器去MyClass类中找匹配的方法
        public void method(Father f)
        public void method(Son s)

        实参f的编译时类型Father,和它最匹配的是public void method(Father f),找到了
        (2)第二步,运行时要去MySub找 public void method(Father f)是否进行了“重写”
        public void method(Father d) {//(3)
            System.out.println("sub--father");
        }
        执行重写方法体
         */
         
         
        my.method(s);//son
        /*
         my变量的编译时类型是MyClass,编译时看MyClass,
        my变量的运行时类型是MySub,运行时看MySub
        (1)第一步,编译器去MyClass类中找匹配的方法
        public void method(Father f)
        public void method(Son s)

        实参s的编译时类型Son,和它最匹配的是public void method(Son s),找到了
        (2)第二步,运行时要去MySub找 public void method(Son s)是否进行了“重写”
        没有重写,还是执行刚刚父类中找到的
        public void method(Son s) {//(2)
            System.out.println("son");
        }
         */
         
         
        my.method(d);//sub--father
        /*
         my变量的编译时类型是MyClass,编译时看MyClass,
        my变量的运行时类型是MySub,运行时看MySub
        (1)第一步,编译器去MyClass类中找匹配的方法
        public void method(Father f)
        public void method(Son s)

        实参d的编译时类型Daughter,和它最匹配的没有,找可以兼容的,public void method(Father f)方法可以兼容

        (2)第二步,运行时要去MySub找 public void method(Father f)是否进行了“重写”
                public void method(Father d) {//(3)
            System.out.println("sub--father");
        }
        执行重写方法体
         */
    }
}
class MyClass{
    public void method(Father f) {//(1)
        System.out.println("father");
    }
    public void method(Son s) {//(2)
        System.out.println("son");
    }
    //(1)和(2)是重载
}
class MySub extends MyClass{//MySub是MyClass的子类
    public void method(Father d) {//(3)
        System.out.println("sub--father");
    }
    public void method(Daughter d) {//(4)
        System.out.println("daughter");
    }
    //(3)和(4)是重载
    //(3)是重写(1)
    //(4)和它们是重载关系,没有重写关系
}
class Father{//Father父亲

}
class Son extends Father{//Son儿子

}
class Daughter extends Father{//Daughter女儿

}