概念
多态 是面向对象三大特征之一。
同一个对象,在不同的时刻表现出来的不同形态。
举例:狗
狗就是狗 狗 dog = new 狗();
我们也可以说 动物 animal = new 狗();
这里狗在不同的时刻表现出来的形态,这就是多态。
多态的前提和体现
- 有继承 / 实现关系
- 方法重写
- 有父类引用指向子类对象
示例代码:
AnimalParent.java
package com.面向对象.Demo22;public class AnimalParent {// 父类public void eat(){System.out.println("这是动物类 都有eat 方法");}
}
Dog.java
package com.面向对象.Demo22;public class Dog extends AnimalParent {// 子类/*** 多态的基本的条件* 1.有继承 或 实现(后面会学习到接口的概念)的关系* 2.方法的重写——子类重写父类的方法* 3.有父类的引用指向子类*/@Overridepublic void eat() {System.out.println("子类(狗类)重写了父类 eat 方法");}
}
AnimalDemo.java
package com.面向对象.Demo22;public class AnimalDemo {public static void main(String[] args) {// 本身的类型指向引用 new 本身的对象Dog dog = new Dog();dog.eat();// 有父类的引用指向子类对象 多态AnimalParent animalParent = new Dog();animalParent.eat();}
}
运行结果:
多态的访问特点
- 成员变量:编译看左边,执行看左边;
- 成员方法:编译看左边,执行看右边。
为什么成员变量和成员方法的访问不一样呢?
∵ 成员方法有重写,而成员变量是没有的。
示例代码:
AnimalParent.java
package com.面向对象.Demo22;public class AnimalParent {public int age = 20;// 父类public void eat() {System.out.println("这是动物类 都有eat 方法");}
}
Dog.java
package com.面向对象.Demo22;public class Dog extends AnimalParent {public int age = 10;public int weight = 20;// 子类/*** 多态的基本的条件* 1.有继承 或 实现(后面会学习到接口的概念)的关系* 2.方法的重写——子类重写父类的方法* 3.有父类的引用指向子类*/@Overridepublic void eat() {System.out.println("子类(狗类)重写了父类 eat 方法");}public void show(){}
}
AnimalDemo.java
package com.面向对象.Demo22;public class AnimalDemo {/*** AnimalParent animalParent = new Dog();* 成员属性 编译阶段是看左边(父类animalParent)执行也是看左边(父类animalParent);* 成员方法 编译阶段是看左边(父类animalParent)执行是看右边(子类Dog);* @param args*/public static void main(String[] args) {/*** 本身的类型指向引用 new 本身的对象* 非多态*/Dog dog = new Dog();dog.eat();System.out.println(dog.age);System.out.println(dog.weight);/*** 有父类的引用指向子类对象* 多态*/AnimalParent animalParent = new Dog();animalParent.eat();System.out.println(animalParent.age);//20,这个age 是父类animalParent里的 age
// System.out.println(animalParent.weight);//报错,Cannot resolve symbol 'weight'(无法解析weight)//成员属性 编译阶段是看左边(父类animalParent),父类没有这个属性,所以报错// animalParent.show();//报错,Cannot resolve method 'show' in 'AnimalParent'// 成员方法 编译阶段是看左边(父类animalParent),父类没有show这个方法,所以报错,//执行虽然看的右边 子类有show(),但是这个show()没有重写父类的show()// (父类没有show())所以,在编译阶段都报错,何谈执行阶段animalParent.eat(); // 输出:子类(狗类)重写了父类 eat 方法//父类和子类都有eat()方法,但是 执行是看右边的(子类Dog)里的eat()// Ctrl + Alt + 鼠标点击eat,可以看到都有那些类里面有eat()方法}
}
下一篇文章: