看了关于thinking in java的书籍对于多态写一下自己的理解
一.多态时成员变量的特点:
1.不管是静态成员变量,非静态成员变量以及final成员变量都不具备多态性
2.简单理解:即编译时看父类型所对应的类是否有该变量如果有编译通过,如果没有编译失败;运行时变量值取自父类型对应的变量的值;一般来成员变量都为私有,只能在本类中修改成员的值
package net.oschina.tkj.chapter8.extend; /** * 父类 * @author Freedom * */ public class ParentClass { public int field = 1; private static int fieldStatic= 1; public final int fieldFinal = 1; public ParentClass(){ System.out.println("parent constructor test domain begin..."); System.out.println("parent field:"+field+" parent fieldStatic:"+fieldStatic+ " parent final field:"+fieldFinal); System.out.println("parent constructor test domain end..."); } } package net.oschina.tkj.chapter8.extend; /** * 子类 * @author Freedom * */ public class SonClass extends ParentClass { public int field = 5; private static int fieldStatic = 5; public SonClass(int field){ System.out.println("son field:"+field);// 就近原则取了参数的值 System.out.println("son field init:"+this.field);// 创建对象时,显示初始化在默认初始化之后,在构造器对参数初始化之前 System.out.println("son constructor test domain begin..."); System.out.println("son field:"+field+" parent fieldStatic:"+fieldStatic+" son final field:"+fieldFinal); System.out.println("son constructor test domain end..."); } }
3.变量赋值的时机
3.1 静态成员变量(类变量):随着类的加载而加载,同时为变量赋值;
3.2成员变量以及final类型的成员:随着对象的创建而存在,首先进行默认初始化赋值,如:基本数据类型int默认值为0,引用类型变量默认值为null;接着在调用父类默认空参构造器之后,进行变量的显示初始化,最后是构造器的特殊初始化
二.多态时成员函数特点
1.静态成员函数:对于静态成员函数来说不具备多态性,不能被子类重写
简言之,在多态时调用静态函数,编译时期看父类型对应的类中是否有该函数,如果没有编译失败,运行时执行的也是父类型对应类中的静态函数
如:下列所示
package net.oschina.tkj.chapter8.extend; /** * 父类 * @author Freedom * */ public class ParentClass { public static void method(){ System.out.println("parent method() run."); } } package net.oschina.tkj.chapter8.extend; /** * 子类 * @author Freedom * */ public class SonClass extends ParentClass { // 子类不能重写父类的静态方法,所以该方法为子类自己的方法 public static void method(){ System.out.println("son method() run."); } }
运行结果:
2.非静态函数
如下例子:
package net.oschina.tkj.chapter8.extend; /** * 父类 * @author Freedom * */ public class ParentClass { /* * 父类中该方法为私有 */ private void f(){ System.out.println("parent f()"); } public static void main(String[] args) { ParentClass clazz = new SonClass(7); clazz.f(); } } package net.oschina.tkj.chapter8.extend; /** * 子类 * @author Freedom * */ public class SonClass extends ParentClass { /* * 子类中创建一个与父类名一样的方法,只是访问权限为public */ public void f(){ System.out.println("parent f()"); } }
运行结果:
因为父类中f()为私有方法,因此在父类执行main函数
上述情况,因为父类的方法为私有,相当于给父类方法加了final,子类无法继承该方法。因此,子类中相同名称的方法,就是一个新的方法(实际开发不建议父类方法名与子类方法名相同阅读性较差)。
因此,多态的前提条件:①类之间需要继承②重写父类的方法(父类的私有方法,静态方法以及final关键字修饰的方法不能被重写)
2.1 满足多态前提时调用一般函数,编译时看父类型对应的类中是否有该方法,如果没有编译错误;运行时,调用子类中的重写的方法