多态 虚方法:可以被子类重写的方法叫作虚方法。 不是虚方法(类方法,final修饰的方法-不能被重写 private修饰的方法 如果跨包继承缺省的方法) 静态绑定:在编译时就可以确定调用哪些方法(不是虚方法)。 动态绑定技术(编译看左边 运行看右边):在编译时调用哪个方法并不能确定 在运行时再确定调用哪个方法。 编译时静态分派:先看这个对象xx的编译时类型,在这个对象的编译时类型中找到能匹配的方法 匹配的原则:看实参的编译时类型与方法形参的类型的匹配程度 A:找最匹配 实参的编译时类型 = 方法形参的类型 B:找兼容(多态) 实参的编译时类型 < 方法形参的类型 运行时动态绑定:再看这个对象xx的运行时类型,如果这个对象xx的运行时类重写了刚刚找到的那个匹配的方法, 那么执行重写的,否则仍然执行刚才编译时类型中的那个匹配的方法 思考:如果调用方法都是动态绑定效率高吗?不好-效率低 如何解决:只有调用虚方法时才采用动态绑定技术
例1:
public class Test4 {
public static void main(String[] args) {
Father f = new Father();
Son s = new Son();
Daughter d = new Daughter();
MyClass my = new MySub();
my.method(f);
my.method(s);
my.method(d);
}
}
class MyClass{
public void method(Father f) {
System.out.println("father");
}
public void method(Son s) {
System.out.println("son");
}
}
class MySub extends MyClass{
public void method(Daughter d) {
System.out.println("daughter");
}
}
编译看左边,第三个对象 d 在MyClass类中找匹配的方法,发现形参列表没有符合的,那就找最符合的,method(Father f)中的形参是Daughter d的父类,直接调用了method(Father f)。发现右边MySub类没有重写该方法,所以直接输出father
例2:
public class Test5 {
public static void main(String[] args) {
Father f = new Father();
Son s = new Son();
Daughter d = new Daughter();
MyClass my = new MySub();
my.method(f);
my.method(s);
my.method(d);
}
}
class MyClass{
public void method(Father f) {
System.out.println("father");
}
public void method(Son s) {
System.out.println("son");
}
}
class MySub extends MyClass{
public void method(Father d) {
System.out.println("daughter");
}
}
第三个对象 d在MyClass类中找匹配的方法发现形参列表没有符合的,那就找最符合的,method(Father f)中的形参是Daughter d的父类,直接调用了method(Father f),但是发现运行看右边MySub类中重写了method(Father f),所以调用MySub类中的方法输出daughter。