Java 动态绑定 和 PHP 延迟绑定的区别

来源:互联网 发布:2016黑马python百度云 编辑:程序博客网 时间:2024/06/11 11:21

众所周知,面向对象语言的一个特点就是“多态”,即一个对象既可以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方法实现的:

<?phpabstract 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指向哪种类型的对象是运行时才确定的。



-----------------------

不确定理解的正确,请多多指教。


0 0