多态:动态绑定

动态绑定

程序绑定的概念:
绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定.

静态绑定:
在程序执行前方法已经被绑定(也就是说在编译过程中就已经知道这个方法到底是哪个类中的方法),此时由编译器或其它连接程序实现。例如:C。
针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定

动态绑定:
后期绑定:在运行时根据具体对象的类型进行绑定。
若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。
动态绑定的过程:

  1. 虚拟机提取对象的实际类型的方法表;
  2. 虚拟机搜索方法签名;
  3. 调用方法。

1、下列代码输出是什么?为什么输出为 private f()?

//: polymorphism/PrivateOverride.java
//Trying to override a private method.
package polymorphism;

import static net.mindview.util.Print.*;

public class PrivateOverride {
    private void f() {
        print("private f()");
    }

    public static void main(String[] args) {
        PrivateOverride po = new Derived();
        po.f();
    }
}

class Derived extends PrivateOverride {
    public void f() {
        print("public f()");
    }
} /*
     * Output: private f()
     */// :~

要点:

  • private 默认为 final,不支持覆盖。
  • 理解静态绑定和动态绑定。
  • 编程规范:函数名避免与父类 private 方法相同,以免发生误解。
  • 将 main 方法移到 PrivateOverride 类外会发现 private 方法无法访问。

2、下列代码输出是什么?为什么?


//: polymorphism/FieldAccess.java
// Direct field access is determined at compile time.
class Super {
    public int field = 0;

    public int getField() {
        return field;
    }
}

class Sub extends Super {
    public int field = 1;

    public int getField() {
        return field;
    }

    public int getSuperField() {
        return super.field;
    }
}

public class FieldAccess {
    public static void main(String[] args) {
        Super sup = new Sub(); // Upcast
        System.out.println("sup.field = " + sup.field + ", sup.getField() = " + sup.getField());
        Sub sub = new Sub();
        System.out.println("sub.field = " + sub.field + ", sub.getField() = " + sub.getField()
                + ", sub.getSuperField() = " + sub.getSuperField());
    }
} /*
     * Output: sup.field = 0, sup.getField() = 1 sub.field = 1, sub.getField() =
     * 1, sub.getSuperField() = 0
     */// :~

要点:

  1. 类中的域是静态绑定的,父类引用直接访问域,会返回父类的值。
  2. 编程规范:域设置为 private,用 getter/setter 访问;避免父类和子类域名相同

3、下列代码输出是什么?为什么?

//: polymorphism/StaticPolymorphism.java
// Static methods are not polymorphic.
class StaticSuper {
public static String staticGet() {
1 Thanks to Randy Nichols for asking this question.
return "Base staticGet()";
}

    public String dynamicGet() {
        return "Base dynamicGet()";
    }
}

class StaticSub extends StaticSuper {
    public static String staticGet() {
        return "Derived staticGet()";
    }

    public String dynamicGet() {
        return "Derived dynamicGet()";
    }
}

public class StaticPolymorphism {
    public static void main(String[] args) {
        StaticSuper sup = new StaticSub(); // Upcast
        System.out.println(sup.staticGet());
        System.out.println(sup.dynamicGet());
    }
} /*
     * Output: Base staticGet() Derived dynamicGet()
     */// :~

要点:

  1. static 方法是静态绑定的

你可能感兴趣的:(多态:动态绑定)