1. 认识多态
面向对象三大特征:封装、继承、多态。
封装:对象代表什么,就得封装对应的数据,并提供数据对应的行为
继承:多个对象共性的属性和方法进行抽取,解决代码重复的问题
继承是多态的前提条件
多态:同类型的对象,表现出的不同形态。对象的多种形态
多态的表现形式:
父类类型 对象名称 = 子类对象;
多态的前提:
1.有继承关系
2.有父类引用指向子类对象
3.有方法重写。
Fu f = new Zi();
多态的好处:
使用父类型作为参数,可以接收所有子类对象。
体现多态的扩展性与便利。
2. 多态调用成员的特点
变量调用:编译看左边,运行也看左边
方法调用:编译看左边,运行看右边
Fu f = new Zi();
左边是父类
调用成员变量:(成员变量会被继承下来)
编译看左边:Javac编译代码的时候,会看左边的父类有没有这个变量,如果有,编译成功,如果没有编译失败。
运行也看左边:Java运行代码的时候,实际获取的就是左边父类中成员变量的值。
调用成员方法:(成员方法,重写的方法,在虚方法表中会把父类的方法进行覆盖)
编译看左边:Javac编译代码的时候,会看左边的父类中有没有这个方法,如果有编译成功,如果没有,编译失败。
运行看右边:java运行代码的时候,实际上运行的是子类中的方法。
3. 多态的优势和弊端
多态的优势: 在多态形态下,右边对象可以实现解耦合,便于扩展和维护。
定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利。
多态的弊端:
不能调用子类的特有功能。
原因? 当调用成员方法的时候,编译看左边,运行看右边。
那么在编译的时候会先检查左边的父类有没有这个方法,如果没有直接报错。
解决方案:
强制类型转换:
将调用类型变回子类类型就可以
转换的时候,要转换成对应的类型,不可以瞎转,否则会报错。
在转换的时候判断要转换的类型是否一致:
if(a instanceof Dog) 布尔类型,如果是结果为true。
新特性: 将判断和强转合在一起
if(a instanceof Dog d) 先判断a是否为Dog类型,如果是,则强转为Dog类型,转换之后变量名为d
如果不是,则不强转,结果直接为false。
4. 多态的综合练习。
动物类:
package polymorphism;
public class Animal {
private String color;
private int age;
//构造方法
public Animal() {
}
public Animal(String color, int age) {
this.color = color;
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(String food) {
System.out.println("动物在吃 " + food);
}
}
狗类:
package polymorphism;
public class Dog extends Animal {
//构造方法
public Dog() {
}
public Dog(String color, int age) {
super(color, age);
}
@Override
public void eat(String food){
System.out.println(getAge() +"岁的" + getColor() + "的狗两只前腿死死的抱着" + food + "猛吃。");
}
public void lookHome(){
System.out.println("狗在看家。");
}
}
人类:
package polymorphism;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/*public void keepPet(Dog dog, String food) {
System.out.println("年龄为" + age + "岁的" + name + "养了一只"+dog.getColor()+"的"+
dog.getAge() +"岁的狗");
dog.eat(food);
}
public void keepPet(Cat cat, String food) {
System.out.println("年龄为" + age + "岁的" + name + "养了一只"+cat.getColor()+"的"+
cat.getAge() +"岁的猫");
cat.eat(food);
}
*/
//使用强转完成方法的调用
public void keepPet(Animal a, String food) {
if(a instanceof Dog d){
System.out.println("年龄为" + age + "岁的" + name + "养了一只"+d.getColor()+"的"+
d.getAge() +"岁的狗");
d.eat(food);
} else if (a instanceof Cat c) {
System.out.println("年龄为" + age + "岁的" + name + "养了一只"+c.getColor()+"的"+
c.getAge() +"岁的猫");
c.eat(food);
}else{
System.out.println("没有这种动物");
}
}
}
测试类:
package polymorphism;
public class Test {
public static void main(String[] args) {
Person p = new Person("大黄",59);
Dog dog = new Dog("棕色",4);
p.keepPet(dog,"chicken");
}
}
标签:String,food,age,多态,概述,public,name
From: https://blog.csdn.net/m0_57132040/article/details/143904924