1.多态
(1)意义
同类型的对象,表现出的不同形态
(2)表现形式
父类类型 对象名称 = 子类对象;
(3)前提
1.有继承或实现关系
2.有父类引用指向子类对象
3.有方法的重写
(4)好处
使用父类类型作为参数,可以接收所有子类对象,体现多态的扩张性与便利
(5)特点
1.调用成员变量的特点:编译看左边,运行也看左边
编译看左边:javac编译代码的时候,会看左边父类中有没有这个变量。如果有,编译成功;如果没有,编译失败
运行也看左边:java运行代码的时候,实际获取的就是左边父类中成员变量的值
2.调用成员方法的特点:编译看左边,运行看右边
编译看左边:javac编译代码的时候,会看左边的父类中有没有这个方法。如果有,编译成功;如果没有,编译失败
运行看右边:java运行代码的时候,实际上运行的是子类中的方法
例:
父类:
package polymorphic;
public class Animal {
String name = "动物";
public void show(){
System.out.println("Animal---show");
}
}
子类:
package polymorphic;
public class Dog extends Animal{
String name = "狗";
@Override
public void show(){
System.out.println("dog---show");
}
}
package polymorphic;
public class Cat extends Animal{
String name = "猫";
@Override
public void show(){
System.out.println("cat---show");
}
}
测试类:
package polymorphic;
public class Text {
public static void main(String[] args) {
//创建对象(多态方式)
Animal an = new Dog();
//调用成员变量:编译看左边,运行也看左边
System.out.println(an.name); //输出:动物
//成员变量:再子类的对象中,会把父类的成员变量也继承下去
//调用成员方法:编译看左边,运行看右边
an.show(); //输出:dog---show
//成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的
}
}
(6)优势
1.在多态形式下,右边对象可以实现解耦合,便于扩展和维护
(解耦合是软件工程中的一个重要概念,它指的是减少程序中各个模块之间的依赖关系,从而提高程序的独立性和可维护性。在软件开发过程中,耦合性(Coupling)是衡量模块间关联程度的指标,包括控制关系、调用关系和数据传递关系。模块间的联系越多,耦合性越强,独立性越差,维护成本也越高)
2.定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利
(7)弊端
不能调用子类的特有功能
解决方法:转换成子类的类型(强制类型转换:可以转换成真正的子类类型,从而调用子类独有的功能)
例:
父类:
package polymorphic;
public class Animal {
String name = "动物";
public void eat(){
System.out.println("动物在吃饭");
}
}
子类:
package polymorphic;
public class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗在吃骨头");
}
public void lookHome(){
System.out.println("狗在看家");
}
}
package polymorphic;
public class Cat extends Animal{
@Override
public void eat(){
System.out.println("猫在吃小鱼干");
}
public void catchMouse(){
System.out.println("猫在捉老鼠");
}
}
测试类:
package polymorphic;
public class Text {
public static void main(String[] args) {
//创建对象(多态方式)
Animal a = new Dog();
//调用成员方法:编译看左边,运行看右边
a.eat(); //正确 输出:狗在吃骨头
//a.lookHome(); <---错误
/*Dog d = (Dog) a; //转换成子类类型
d.lookHome(); //输出:狗在看家
Cat c = (Cat) a; //转换时不能转换成其他类型 会报错
c.catchMouse(); //错误
*/
//以上可以改为:
//先判断a是否为Dog类型,如果是,则强制转换成Dog类型,转换之后变量名为d,如果不是,则不强转,结果为false
if(a instanceof Dog d){
d.lookHome();
}else if(a instanceof Cat c){
c.catchMouse();
}else{
System.out.println("没有这个类型,无法转换");
}
}
}
//输出:狗在吃骨头
// 狗在看家