多态:事物的多种体现形态
父类的引用指向了自己的子类的对象。
前提:类与类之间有关系,要么继承或实现。
好处:提高了代码的扩展性
弊端:但是只能使用父类的引用指向子类和父类同样的方法。
类型转换:向上转型 向下转型
instanceof 用于判断对象是属于哪种类型。
多态(父类的引用指向子类对象)在代码中的特点(注意事项):
在多态中非静态成员函数的特点:
在编译时期: 参阅引用型变量所属类中是否有调用的方法。如果有,编译通过,否则编译失败。
在运行时期: 参阅对象所属的类中是否有调用的方法。
简单的总结:成员函数在多态调用时,编译看左边,运行看右边。
在多态中,非静态成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)
在多态中,静态成员变量/函数的特点:
无论编译和运行,都参照左边。
Java对非静态方法的调用是采取动态绑定(运行时才判断)的方法,
对静态成员、属性的调用是采取静态绑定(编译时就判断)的方法。
---------------------示例代码----------------------------------------
class Fu{
public String name = "Fu";
public static String address= "Fu address";
public void method1(){
System.out.println("Fu method1");
}
public void method2(){
System.out.println("Fu method2");
}
public static void method4(){
System.out.println("static Fu method4");
}
}
class Zi extends Fu{
public static String address= "Zi address";
public String name = "Zi";
public void method1(){
System.out.println("Zi method1");
}
public void method2(){
System.out.println("Zi method2");
}
public void method3(){
System.out.println("Zi method3");
}
public static void method4(){
System.out.println("static Zi method4");
}
public void method5(){
System.out.println(name);
}
public void method6(){
System.out.println(super.name);
}
public void method7(){
System.out.println(name);
}
}
public class Test{
public static void main(String args[]){
/*关于非静态/和静态函数的演示*/
//Fu z = new Zi();
//z.method3();//编译会报错
//z.method2();//Zi method2
/*为什么会出现下面的这种情况?
因为静态方法是静态绑定好的,
无论是在什么情况在最初的时候就已经在静态方法区把静态方法和类绑在一起,所以静态方法不存在覆盖
不管引用指向哪个对象不没有用。
而非静态方法是在new对象的时候把非静态方法和对象绑定一起,通过对象去调用非静态方法。
*/
//z.method4(); //static Fu method4
//Zi z1 = new Zi();
//z1.method4();//static Zi method4
/*成员变量的演示*/
Zi z2 = new Zi();
System.out.println(z2.name);//Zi
//(在堆内存中同时存在两个变量,
//那么会先找定义引用的那个类的那个变量值 和 方法不同)
Fu z4 = new Zi();
System.out.println(z4.name);//Fu
/*为什么会出现这种情况?
在非静态成员变量中,对象的引用去取成员变量是根据左边的类去找相对应的值
在静态成员变量中是根据静态绑定的原理一样一开始就把类和静态成员绑定在一起。
不管自己指向哪个对象
静态的成员或方法都是直接和类进行绑定在一起称之为静态绑定
java对非静态方法的调用是采取动态绑定(运行时才判断)的方法,
对静态成员、属性的调用是采取静态绑定(编译时就判断)的方法。
*/
//Fu z3 = new Zi();
//System.out.println(z3.address);//Fu address
//Zi z4 = new Zi();
//System.out.println(z4.address);//Zi address