第八章多态

2017-08-24  本文已影响0人  小倩的宁采臣

Overview

最近在学习Thinking in Java这部java经典,书非常不错,作者有非常深厚的编程功底,讲解知识时候说的很透彻,而且有一定发散,深入浅出,是一本阅读起来非常舒服。目前阅读到第八章,除了第五章初始化与清理里的垃圾回收机制有些难度以外,其他章节有一定编程经验的都可以看懂。从第八章开始,内容开始增多,各种重要知识点开始出现,如不好好总结很可能会漏掉一些细节,所以从这里开始对第八章进行总结。

有关垃圾回收的知识我准备在以后在整理jvm相关知识时再做详细总结。

Contents

初始化的顺序还要注意在第五章中提到的知识,静态对象要先于非静态对象。

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 JavaTest{
    public static void main(String[] args) {
        Super sup = new Sub(); //向上转型
        //这里在直接访问域的时候,并没有出现理想中的多态
        System.out.println("sup.field: " + sup.field + "\nsup.getField: " + sup.getField() + "\n");
        Sub sub = new Sub();
        System.out.println("sub.field: " + sub.field + "\nsub.getField: " + sub.getField() + "\nsub.getSuperField():" + sub.getSuperField());
    }
}

输出为:
sup.field: 0
sup.getField: 1
sub.field: 1
sub.getField: 1
sub.getSuperField():

当Sub对象转型为Super引用时,任何域访问操作都将由编译器解析,由于多态采用的是动态绑定,而不是靠编译器,所以无法完成多态。

在上面的例子中,一个sub对象中有两个叫做field的域(Super.field和Sub.field),然而在引用sub中的field时所产生的默认域并非Super版本的field,因此必须显示的指明super.field。

在实际编程中非常不赞成出现这样的代码,这样的代码难以阅读,进而难以维护。

public class Test1 {
    public void printStr(String s){
        System.out.println("this is test1.printStr");
        System.out.println(s);
    }

    public void printStr2(String s){
        printStr(s);
    }
}
public class Test2 extends Test1 {
    public void printStr(String s){
        System.out.println("this is test2.printStr");
        System.out.println(s);
    }
    public static void main(String[] args) {
        Test1 test = new Test2();
        test.printStr2("test");
    }
}

输出为:
this is test2.printStr
test

这是第八章练习10的运行效果,和上面的结果放在一起对比看起来会更佳直观,这里的printStr()方法被覆盖了,即使是Test1的方法调用printStr()也会调用被覆盖的方法,与上面的变量覆盖是不同的。

上一篇 下一篇

猜你喜欢

热点阅读