一、多态中的成员访问特点
Father f=new Son()
1.成员变量:编译看左边,运行看左边
f只能访问父类中定义过的成员变量,不能访问子类中特有的成员变量,并且该成员变量的值与父类一致。
2.构造方法:创建子类对象时,会访问父类的构造方法,先对父类进行初始化。
3.成员方法(非静态):编译看左边,运行看右边
f只能访问父类中定义过的成员方法,不能访问子类中特有的成员方法。如果该方法被子类重写,则执行子类中该方法;如果未被重写,则执行父类中该方法。
4.静态方法:编译看左边,运行看左边
静态和类相关,算不上重写,所以访问的还是父类中该静态方法。
举例:
class Father{
public int num=10;
public void method(){
System.out.println("method of father");
}
public void methodOfFather(){
System.out.println("only method of father ");
}
public static void sMethod(){
System.out.println("static method of father");
}
}
class Son extends Father{
public int num=20;
public int sNum=30;
public void method(){
System.out.println("method of son");
}
public void methodOfSon(){
System.out.println("only method of son ");
}
public static void sMethod(){
System.out.println("static method of son");
}
}
public class Polymorphism {
public static void main(String[] args) {
Father f=new Son();
System.out.println(f.num);//输出10,输出父类成员变量
//System.out.println(f.sNum);报错:f不能访问子类特有的成员变量
f.method();//输出:method of son,输出子类成员方法
f.methodOfFather();//输出:only method of father ,输出父类成员方法
//f.methodOfSon();报错:f不能访问子类特有的成员方法
f.sMethod();//输出:static method of father,输出父类静态成员方法
}
}
总结:f归根结底还是个父类,所以f的成员变量,静态方法就相当于父亲的固有特征不可改变,但是多态可以让f执行子类从父类那重写的方法,就相当于父亲只会开机动三轮,儿子向父亲学了之后会开汽车了,多态就可以让父亲也可以开汽车了;但是多态不能让f执行子类自己特有的方法,就比如儿子自己学会开小飞机了,不管小飞机还是轰炸机,父亲不会还是不会。
Father f=new Son()这是向上转型,
可以看出多态的弊端就是不能访问子类特有成员方法,
可以用向下转型解决。
二、向下转型
Father f=new Son()
Son s=(Son) f;
举例:
class Father{
public int num=10;
public int fNum=50;
public void method(){
System.out.println("method of father");
}
public void methodOfFather(){
System.out.println("only method of father ");
}
public static void sMethod(){
System.out.println("static method of father");
}
}
class Son extends Father{
public int num=20;
public int sNum=30;
public void method(){
System.out.println("method of son");
}
public void methodOfSon(){
System.out.println("only method of son ");
}
public static void sMethod(){
System.out.println("static method of son");
}
}
public class Polymorphism {
public static void main(String[] args) {
Father f=new Son();
Son s=(Son)f;
System.out.println(s.num);//输出:20
System.out.println(s.sNum);//输出:30
System.out.println(s.fNum);//输出:50
s.method();//输出:method of son
s.methodOfFather();//输出:only method of father
s.methodOfSon();//输出:only method of son
s.sMethod();//输出:static method of son
}
}
总结:子类有的就用子类的,子类没有的用父类的。