多态
什么是多态?
在Java中,多态(Polymorphism)是面向对象编程的三大特性之一,另外两个是封装(Encapsulation)和继承(Inheritance)。多态是这三个特性中最重要、最核心的一个。
多态的主要含义是“多种形态”,它可以分为方法重载和方法重写两种形式,可见多态是针对方法而言的。
方法重载(Overloading)是指在同一个类中,方法名相同但参数列表(参数类型、数量、顺序)不同的方法。这是编译时的多态。编译器会根据参数列表的不同来区分不同的方法。方法重载使得一个类可以有多个名称相同但参数不同的方法,增强了代码的可读性和可维护性。
方法重写(Overriding)是指子类中定义了一个与父类中同名同参数的方法。这是运行时的多态。当通过子类的对象调用该方法时,会执行子类中的方法,而不是父类中的方法。方法重写使得子类可以根据需要覆盖父类的方法,从而实现更具体、更个性化的行为。
多态的编译和运行
调用成员变量:编译看左边,运行也看左边。 编译看左边:javac编译代码时,会看左边的父类中有没有这个变量,如果有,编译成功,否则编译失败。 运行也看左边:java运行代码时,实际获取的就是左边父类中的成员变量的值。
调用成员方法:编译看左边,运行看右边。 编译看左边:javac编译代码时,会看左边的父类中有没有这个变量,如果有,编译成功,否则编译失败。 运行看右边:java运行代码时,实际上运行的就是子类中的方法。
多态的前提?
-
有继承/实现的关系。
-
有父类引用指向子类对象(就是把子类的对象赋值作为父类的类型)。
-
需要有方法重写。
多态的调用的理解:
public class Demo {
public static void main(String[] args){
Animal a = new Dog();
a.show();//打印dog
System.out.println(a.name);//打印动物
}
}
public class Animal {
String name = "动物";
public void show(){
System.out.println("aimal");
}
public class Dog extends Animal{
String name = "狗狗";
@Override
public void show(){
System.out.println("dog");
}
public class Cat extends Animal{
String name = "猫猫";
@Override
public void show(){
System.out.println("cat");
}
-
由于a是Animal类型,所以默认都会从Animal这个类中去找。
-
成员变量:在子类的对象中,会把父类中的成员变量也继承下的。
扫描二维码关注公众号,回复: 17421649 查看本文章 -
成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的。
多态的优势?
方法中,使用父类型作为参数,可以接受所有子类对象,可以做到一方法多用。
多态的弊端:
-
不能调用子特有的功能:
原因:调用成员方法时,编译看左边,运行看右边,编译时父类没有子类的特有方法,所以编译报错。
解决方案:强制类型转换,把对象的类型由父类转换成对应的子类。但是不能瞎转,如果转成其他类型会报错,例如:
Animal a = new Dog(); Dog b = (Dog) a;//ok Cat c = (Cat) a;//这样做会报错 //所以引出问题,如果a多态创建时的子类我不知道怎么办。
-
但在进行强制类型转换时我不知道多态的子类怎么办
工具:可以用instanceof
if(a instanceof Dog){ Dog b = (Dog) a; } //上面三行等价于if(a instanceof Dog b){} else if(a instanceof Cat){ Cat c = (Cat) a; } else sout("没有啊"); //上面三行等价于if(a instanceof Cat c){}