【Java编程思想】第八章 多态

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chuxue1989/article/details/88209345

java中特性封装和继承都是为了多态服务的

一、定义

多态:动态绑定、后期绑定、运行时绑定。
在编译的时候编译器并不知道该引用的具体类型,只有到运行的是通过该引用知道具体的类型,调用该具体类型的方法。

多态要求必须有某种机制:在运行的时候能判断出对象的类型,他是通过在对象中安置某种“类型信息”

二、多态缺陷

2.1 覆盖私有方法

这个是会产生疑惑的地方,在第七章中fianl修饰方法中也有解释,具体的就是只有非private方法才可以覆盖也就是说private方法不会存在覆盖,更别提多态的发生。这里只要区别对待就行,private方法是属于每个类的,基类和派生类都有相同的private方法,他们是没有关系,这个时候最好不要名字相同。

2.2 字段和静态方法

package com.hfview.defect;

import org.junit.Test;

public class demo {

    @Test
    public void test(){

        A b= new B();
        System.out.println(b.count);

        b.getCount();
        
		 /**
         * output:
         * 10
         * B of this.count:20
         * B of super.count:10
         * 
         */
		
    }

}

class A{

    public int count = 10;

    public void getCount(){
        System.out.println("A of count:"+count);
    }

}

class B extends A{

    public int count =20;

    public void getCount(){
        System.out.println("B of this.count:"+this.count);

        System.out.println("B of super.count:"+super.count);
    }

}

任何的域(字段)都将由编译器解析,因此不是多态的。

就像上面调用b.count编译器缺点b是A类型的,所以b.cont=10;因为方法是可以多态的,所以调用getCount会动态绑定到子类中。通过super可以很方便的访问基类的域信息

尽量不要对基类和派生类的域赋相同的名字,这种做法容易类令人混淆

三、构造器和多态

  • 调用基类构造器,这个步骤会不断的反复递归下去,首先是构造这种层次的根,然后是下一层导出类,直到最后的导出类
  • 按照生命顺序调用成员的初始化方法
  • 盗用导出类的构造函数主体

3.1 构造器内部的多态方法行为

在构造器总调用覆盖的方法。

package com.hfview.constructor;

import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.junit.Test;

public class demo1 {


    @Test
    public void method1(){
        B b = new B();
    }

}

class A{

    void draw(){
        System.out.println("A of draw()");
    }

    public A(){
        System.out.println("A constructor invoke:before draw");

        draw();

        System.out.println("A constructor invoke:after draw");
    }
}

class B extends A{

    private int count = 1;

    void draw(){
        System.out.println("B of draw()_count:"+count);
    }

    public B(){
        System.out.println("B constructor invoke");
    }

}

一个动态绑定的方法调用会向外深入到继承层次的结构内部,它可以调用导出类的方法。

但是有个缺点,因为在基类中调用导出类的方法,这个时候导出来其实还没有初始化,这个会有问题

所以构造器中应该避免调用多态的方法,如果调用方法调用private的方法

猜你喜欢

转载自blog.csdn.net/chuxue1989/article/details/88209345