众所周知,面向对象语言的一个特点就是“多态”,即一个对象既可以is a A,同时也可是继承自B以至于is a B。于是对于对象调用方法来讲,既可能调用父类的方法,也可能是调用子类的方法。对于Java语言:
public class Parent{
public void sayHi(){
System.out.println("Parent says hi.");
}
}
public class Child extends Parent{
public void sayHi(){
System.out.println("Child says hi.");
}
}
public class TestDemo{
public static void main(String [] args){
Parent p = new Child();
p.sayHi();
System.out.println();
}
}
对于TestDemo中的p,声明为Parent类型,实现为Child类型,当编译时,p被认为是Parent类型,如果终止在这里,很明显当p调用sayHi时会调用Parent类的sayHi方法。但此时还未运行,只是编译完成了,当运行时,p会先被赋予Child类型的一个引用,首先会在Child类中寻找sayHi()方法,于是,当p.sayHi()时,会出现“Child says hi.”的输出,也就是编译时p被认为是Parent类型,只有运行时,p才会绑定其对应的方法Child::sayHi()。
对于Java来说,有一种比较特殊的方法,即静态方法(static method),对于静态方法子类是不能继承的,因为静态方法是属于类的,而不是属于对象的,于是对于以下类:
public class Parent{
public void sayHi(){
System.out.println("Parent says hi.");
}
public static void sayBye(){
System.out.println("Parent says bye.");
}
}
public class Child extends Parent{
public void sayHi(){
System.out.println("Child says hi.");
}
public static void sayBye(){
System.out.println("Child says bye.");
}
}
<pre name="code" class="java">public class TestDemo{
public static void main(String [] args){
Parent p = new Child();
p.sayHi();
p.sayBye();
System.out.println();
}
}
可以看到,虽然p在运行时是以Child类型去调用sayHi方法,但是对于static类型的方法sayBye,p依然是调用Parent类的方法,这是因为static类型的方法不能被继承所以也就没有动态绑定一说了。
对于Java类,若Parent被声明为abstract类型即:
public abstract class Parent {
public void sayHi(){
System.out.println("Parent says hi.");
}
public static void sayBye(){
System.out.println("Parent says bye.");
}
public static Parent create(){
return new Parent();
}
}
会发现对于这一行
return new Parent();
是编译不通过的,因为Parent是抽象类,不能实例化,能做的只有return this;
对于php类,由于php为弱类型语言,一个对象使用前无需声明,且不支持Parent $p = new Child();类型的对象赋值方式,故没有到底是调用哪个SayHi的担心,因为首先他是一个Child类型的对象,会在Child类中查找对应方法,实在找不到才会去Parent中查找。
但php中也有一种叫做延迟绑定的东西,这个是通过static方法实现的:
<?php
abstract class Parent1{
public static function sayHi(){
return new static();
}
}
class Child extends Parent1
{
}
print_r(Child::sayHi());
?>
此时调用sayHi()的对象是Child类型的,而非Parent类型的,通过static关键字,实现当方法调用时才绑定对应的对象(类),我感觉类似Java的this关键字,当return this的时候,具体this指向哪种类型的对象是运行时才确定的。
-----------------------
不确定理解的正确,请多多指教。