Think in Java学习笔记 第八章 多态

多态这一章很多是说的是设计思想。多态的好处就不说了,网上有太多的文章来描述。下面主要对书里面一些抽象的文字进行解释。

如果一种语言想实现动态绑定,就必须拥有某种机制,以便在运行时能够判断对象的类型,从而调用恰当的方法。也就是说编译器一直不知道对象的类型,但是方法调用机制能找到正确的方法体,并加以调用。

我们知道通过一个对象头能够找到该对象所属的类的信息,这样在运行的时候,我们找到该类的方法区中的方法,然后进行调用。值得注意的是,这部分是在运行阶段进行的,在编译阶段,我们是不能够得到一个对象的准确的类型的。

Java中除了static方法和final方法(private方法属于final方法)之外,其他所有的方法都是后期绑定。这意味着通常情况下,我们不必判定是否应该进行后期绑定——它会自动发生。

首先说static方法,在Javastatic方法指的是类的静态方法。这些方法存放在方法区中。子类继承父类之后,如果重写了该方法,前面父类的方法只是被隐藏了,并没有消失。static方法不是动态绑定的,就是说我们调用某个对象的静态方法时,其在编译阶段就确定下来是哪一个方法了。

public class Test {

    static void printAOrB(A a) {
        a.print();
    }

    public static void main(String[] args) {
        A b = new B();
        //输出A
        printAOrB(b);
    }
    
}

class A {
    static void print() {
        System.out.println("输出A");
    }
}

class B extends A {
    static void print() {
        System.out.println("输出B");
    }

}

然后说下finalprivate包括在内)方法。当父类中有final方法的时候,子类时认为这个final方法不能够被重写,只能够使用父类中的该方法。所以编译器能够确定这个方法一定是属于父类的,就会直接调用。

只有非private方法才能够被覆盖,但是还需要密切注意覆盖private方法的现象。这是虽然编译器不会报错,但是也不会按照我们所期望的来执行。确切的说,在导出类中,对于基于基类中的private方法,最好采用不同的名字。

private方法,要么子类认为其不存在(private),要么父类告知子类不能够进行重写(final),这个时候多态性就会消失,统一使用父类中的方法。所以在子类中,我们想要真正实现各自的方法,应该采用一个与父类中方法不同的名字。

class A {
    private void print() {
        System.out.println("输出A");
    }

    public static void main(String[] args) {
        A a = new B();
        //输出A
        a.print();
    }
}

class B extends A {
    void print() {
        System.out.println(输出B");
    }

}

在任何构造器内部,整个对象可能只是部分形成——我们知道其父类对象肯定已经完成初始化了。如果构造器只是在构建对象过程中的一个步骤,并且该对象所属的类是从这个构造器所属的类导出的,那么导出部分在当前构造器正在被调用的时候仍旧是没有被初始化的。然而,一个动态绑定的方法调用却会向外深入到继承层次结构内部,它可以调用导出类中的方法。如果我们是在构造器内部这样做,那么就可能会调用某个方法,而这个方法所操纵的成员可能还未初始化——这肯定会导致灾难。

Emmm,上面这段话是在是太拗口难以理解了。简单来说就是在执行某个类的构造器时,其父类的构造器肯定已经执行完成了。如果在父类构造器执行的时候调用了父类的方法,而这个父类的方法在子类中又有被重写过,那就可能会有问题。因为这个时候不能保证所有的子类属性都能够被正确的初始化。举个简单的例子吧:


class A {

    A() {
        System.out.println("start init A");
        print();
        System.out.println("complete init A");
    }

    void print() {
        System.out.println("输出A");
    }
}

class B extends A {

    private int x = 1;

    B(int a) {
        x = a;
        print();
    }

    void print() {
        System.out.println(x);
    }
    
}

/**
 * Test
 */
public class Test {
    public static void main(String[] args) {
        A a = new B(11);
    }
}

输出的值为:

start init A
0
complete init A
11

这个输出结果我一直有一个点不太理解,希望有朋友能够帮我解惑,为什么父类构造器执行的时候会调用子类的方法。
而至于在父类中输出0则是因为在父类构造器在执行的时候,子类的构造器还没有执行,其中所有的变量都是0值。

在编写构造器时有一条有效的准则:“用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他的方法”。在构造器内唯一能够安全调用的那些方法是基类中的final方法(也适用于private方法,它们自动属于final方法)。这些方法不能被覆盖,也就不会出现上述令人惊讶的问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352