一、多态概述
多态,根据名字我们就可以知道这是什么。就是说同一个对象,在不同时刻表现出不同的形态
举例:猫
我们可以说猫是猫:猫 cat = new 猫();
我们也可以说猫是动物:动物 animal = new 猫();
这里猫在不同时刻表现出不同的形态,这我们称之为多态
多态的前提和体现
- 有继承/实现关系
- 有方法重写
- 有父类引用指向子类对象
二、案例展示
下面给大家展示一个多态的案例
对于多态,需要记住八个字“编译看左边, 执行看右边”
下面展示一些 猫对象代码
。
package TEXT01;
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void play(){
System.out.println("和小狗玩");
}
}
下面展示一些 动物对象代码
package TEXT01;
public class Animal {
public void eat(){
System.out.println("吃东西");
}
}
下面展示一些 测试类代码
package TEXT01;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
Animal cat = new Cat();
//编译的话编译Animal,运行的话则运行Cat, 如果Cat中没有这方法, 则在Animal中找
cat.eat();
// cat.play();
//Animal对象中并无play方法,所以编译不通过,因此不能调用play方法
}
}
三、多态中成员访问特点
- 成员变量:编译看左边, 执行看左边
- 成员方法:编译看左边, 执行看右边
为什么成员变量和成员方法的访问不一样呢?
- 因为成员方法有重写, 而成员变量没有
四、多态中成员访问特点案例演示
下面展示一些 猫对象代码
。
package TEXT01;
public class Cat extends Animal {
public int age = 188;//定义猫的年龄
public int weight = 200;//定义猫的体重
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void play(){
System.out.println("和小狗玩");
}
}
下面展示一些 动物对象代码
package TEXT01;
public class Animal {
public int age = 40;//定义动物的年龄
public void eat(){
System.out.println("吃东西");
}
}
下面展示一些 测试类代码
package TEXT01;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
Animal cat = new Cat();
//编译的话编译Animal,运行的话则运行Cat, 如果Cat中没有这方法, 则在Animal中找
cat.eat();
// cat.play(); //Animal对象中并无play方法,所以编译不通过,因此不能调用play方法
System.out.println(cat.age);
//访问的成员变量是父类的
// System.out.println(cat.weight);
//报错,因为父类中没有weight这个成员变量
}
}
在访问成员变量中,可以看到是访问的是父类中的age,并将父类中的age输出出来,这是为什么呢?
原因是Animal cat = new Cat(); , 虽然对象是Cat类型,但是在外界看来,引用类型依然是Animal,因此访问的是Animal对象的内容
五、多态的好处和弊端
- 多态的好处:提高了程序的扩展性
-
具体表现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作
- 多态的弊端: 不能使用子类的特有功能
六、多态的好处和弊端案例演示
package TEXT01;
/*
操作对象
*/
public class AnimalOperator {
public void usAnimal(Animal animal){
//形参引用类型用Animal 这就不用分Dog还是猫
animal.eat();
}
}
package TEXT01;
/*
动物对象
*/
public class Animal {
public void eat(){
System.out.println("吃东西");
}
}
package TEXT01;
/*
猫对象
*/
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void play(){
System.out.println("和小狗玩");
}
}
package TEXT01;
/*
狗对象
*/
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗啃骨头");
}
}
package TEXT01;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
/*
创建动物对象
*/
Animal cat = new Cat();
Animal dog = new Dog();
//创建操作对象
AnimalOperator ao = new AnimalOperator();
ao.usAnimal(dog);//调用狗对象中的方法
ao.usAnimal(cat);//调用猫对象中的方法
}
}
可见,在操作对象的时候,我们采用父类类型作为形式参数的数据类型,比用具体的类型好很多,因为一个程序可以有很多种对象,与之相比,父类的对象的显得比较少了,因此直接使用父类的类型作为形参的引用类型,可以有利于代码的复用性
七、多态中的转型
-
向上转型
从子到父
父类引用指向子类对象 -
向下转型
从父到子
父类引用转向子类对象
package TEXT01;
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
/*
创建动物对象
从父类到子类
向上转型
*/
Animal cat = new Cat();
Animal dog = new Dog();
//创建操作对象
AnimalOperator ao = new AnimalOperator();
ao.usAnimal(dog);//调用狗对象中的方法
ao.usAnimal(cat);//调用猫对象中的方法
/*
向下转型
强制转化
转型后可以访问子类的特有功能
*/
Cat newCat = (Cat)cat;
newCat.play();
}
}
- 通过强制转化(向下转型),我们就可以访问子类中的特有功能了
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/95047.html