多态前提和体现:
有继承关系
有方法重写
有父类引用指向子类对象
父 f = new 子();
有多态时的子父类间的成员变量、成员方法、构造方法之间的特点:
-
多态中 成员变量的访问特点:编译看左边,运行看左边
-
多态中 成员方法的访问特点:编译看左边,运行看右边
-
多态中 静态方法的访问特点:编译看左边,运行看左边
-
多态中 静态方法的访问特点:创建子类对象的时候,访问父类的构造方法,对父类数据初始化
以下是代码示例以助理解
/**
* 多态中 成员变量的访问特点:编译看左边,运行看左边
*/
public class ExtendsDemo1 {
public static void main(String[] args) {
Child child = new Child();
System.out.println(child.num2);//20
Father child1 = new Child();
//父类引用对象,取父类中的值:运行看左边
System.out.println(child1.num2);//200
//报错:编译看左边,Father中无num变量,所以编译不通过
System.out.println(child1.num1);
GrandFather child3 = new Child();
//祖父类引用对象,取祖父类中的值:运行看左边
System.out.println(child3.num2);//2000
}
}
class GrandFather {
public int num2 = 2000;
}
class Father extends GrandFather {
public int num2 = 200;
}
class Child extends Father {
public int num1 = 10;
public int num2 = 20;
}
/**
* 多态中 成员方法的访问特点:编译看左边,运行看右边
*/
public class DuoTaiDemo2 {
public static void main(String[] args) {
Child1 child = new Child1();
//运行看右边:输出的是子类对象中的method方法
child.method();//20
child.show();//20
Father1 child1 = new Child1();
//运行看右边:输出的是子类对象中的method方法
child1.method();//20
//编译看左边:Father类中没有此方法,所以报错
child1.show();
GrandFather1 child3 = new Child1();
//运行看右边:输出的是子类对象中的method方法
child3.method();//20
}
}
class GrandFather1 {
public int num2 = 2000;
public void method() {
System.out.println(num2);
}
}
class Father1 extends GrandFather1 {
public int num2 = 200;
public void method() {
System.out.println(num2);
}
}
class Child1 extends Father1 {
public int num1 = 10;
public int num2 = 20;
public void method() {
System.out.println(num2);
}
public void show() {
System.out.println(num2);
}
}
/**
* 多态中 静态方法的访问特点:编译看左边,运行看左边
*/
public class DuoTaiDemo3 {
public static void main(String[] args) {
Child2 child = new Child2();
//运行看左边:输出的是子类对象中的method方法
child.method();//子类---静态
Father2 child2 = new Child2();
//运行看左边:输出的是父类对象中的method方法
child2.method();//父类---静态
//编译看左边:Father类中没有此方法,所以报错
child2.show();
GrandFather2 child3 = new Child2();
//运行看左边:输出的是祖父类对象中的method方法
child3.method();//祖父类---静态
}
}
class GrandFather2 {
public static void method() {
System.out.println("祖父类---静态");
}
}
class Father2 extends GrandFather2 {
public static void method() {
System.out.println("父类---静态");
}
}
class Child2 extends Father2 {
public static void method() {
System.out.println("子类---静态");
}
public void show() {
System.out.println("子类---静态---show");
}
}
多态时子父类成员之间的访问特点的内存图解:
/**
* 多态时子父类成员之间的访问特点的内存图解
*/
public class DuoTaiDemo4 {
public static void main(String[] args) {
Fu f = new Zi();
System.out.println(f.age);//40
f.show();//子类--show
}
}
class Fu{
public int age = 40;
public Fu(){}
public void show(){
System.out.println("父类--show");
}
}
class Zi extends Fu{
public int age = 20;
public Zi(){}
public void show(){
System.out.println("子类--show");
}
public void method(){
System.out.println("子类--show");
}
}
多态时子父类成员之间的访问特点的内存图解.png
多态的优缺点
优点:
提高了代码的维护性(继承)
提高了代码的扩展性(多态)
缺点:
不能使用子类特有功能(编译看左边)
若要使用则需要强制转换(对象转型):
向上转型(把子变父):Fu f = new Zi();
向下转型(把父变子):Zi z = (Zi)f;//Zi与Fu是有关系的(子父类,接口实现类)
对象转型图解
对象转型图解
多态几种变现形式:
A:具体类多态(开发中很少遇到)
B:抽象类多态(常用)
C:接口多态(最常用)
多态的2种表现形式
网友评论