先赞后看,养成习惯!!! ^ _ ^ ❤️ ❤️ ❤️
码字不易,大家的支持就是我坚持下去的动力,点赞后不要忘记关注我哦
个人主页:伯明翰java
文章专栏:JavaSE
如有错误,请您指正批评 ^ _ ^
1 多态的概念
多态就是不同类的对象对同一消息做出响应。即同一个接口,使用不同实例而执行不同的操作。多态分为编译时多态(重载)和运行时多态(重写)。它使程序具有良好的灵活性和扩展性。
1.1多态实现的条件
- 必须在继承体系下
- ⼦类必须要对⽗类中⽅法进⾏重写
- 通过⽗类的引⽤调⽤重写的⽅法
多态体现:在代码运⾏时,当传递不同类对象时,会调⽤对应类中的⽅法。
java
public class Animal {
String name;
int age;
public Animal(String name, int age){
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(name + "吃饭");
}
}
public class Cat extends Animal{
public Cat(String name, int age){
super(name, age);
}
@Override
public void eat(){
System.out.println(name+"吃⻥~~~");
}
}
public class Dog extends Animal {
public Dog(String name, int age){
super(name, age);
}
@Override
public void eat(){
System.out.println(name+"吃⻣头~~~");
}
}
///////////////////////////////分割
线//////////////////////////////////////////////
public class TestAnimal {
// 编译器在编译代码时,并不知道要调⽤Dog 还是 Cat 中eat的⽅法
// 等程序运⾏起来后,形参a引⽤的具体对象确定后,才知道调⽤那个⽅法
// 注意:此处的形参类型必须时⽗类类型才可以
public static void eat(Animal a){
a.eat();
}public static void main(String[] args) {
Cat cat = new Cat("元宝",2);
Dog dog = new Dog("⼩七", 1);
eat(cat);
eat(dog);
}
}
当类的调⽤者在编写eat 这个⽅法的时候,参数类型为Animal(⽗类),此时在该⽅法内部并不知道,也不关注当前的a引⽤指向的是哪个类型(哪个⼦类)的实例.此时a这个引⽤调⽤eat⽅法可能会有多种不同的表现(和a引⽤的实例相关),这种⾏为就称为多态.
1.2 重写
写是⼦类对⽗类⾮静态、⾮private修饰,⾮final修饰,⾮构造⽅法
等的实现过程进⾏重新编写,返回值和形参都不能改变。即外壳不变,核⼼重写!重写的好处在于⼦类可以根据需要,定义特定于⾃⼰的⾏为。也就是说⼦类能够根据需要实现⽗类的⽅法。
- ⼦类在重写⽗类的⽅法时,⼀般必须与⽗类⽅法原型⼀致:返回值类型⽅法名 (参数列表)要完全⼀致。
- 被重写的⽅法返回值类型可以不同,但是必须是具有⽗⼦关系的。
- 访问权限不能⽐⽗类中被重写的⽅法的访问权限更低。例如:如果⽗类⽅法被public修饰,则⼦类中重写该⽅法就不能声明为protected。
- ⽗类被static、private修饰的⽅法、finaly修饰的方法、构造⽅法都不能被重写。
- 重写的⽅法,可以使⽤@Override 注解来显式指定.有了这个注解能帮我们进⾏⼀些合法性校验.例如不⼩⼼将⽅法名字拼写错了(⽐如写成aet),那么此时编译器就会发现⽗类中没有aet⽅法,就会编译报错,提⽰⽆法构成重写.
重写和重载的区别
方法重载:同一个类中可以有多个同名方法,它们具有不同的参数列表。虽然方法名相同,但可以根据传入的参数不同,编译器会在编译时确定调用哪个方法。

静态绑定 :也称为前期绑定(早绑定),即在编译时,根据⽤⼾所传递实参类型就确定了具体调⽤那个⽅法。典型代表函数重载。
动态绑定:也称为后期绑定(晚绑定),即在编译时,不能确定⽅法的⾏为,需要等到程序运⾏时,才能够确定具体调⽤那个类的⽅法。
向上转型和向下转型
向上转型
向上转型:实际就是创建⼀个⼦类对象,将其当成⽗类对象来使⽤。
java
Animal animal = new Cat("元宝",2);
animal是⽗类类型,但可以引⽤⼀个⼦类对象,因为是从⼩范围向⼤范围的转换
java
public class TestAnimal {
// 2. ⽅法传参:形参为⽗类型引⽤,可以接收任意⼦类的对象
public static void eatFood(Animal a){
a.eat();
}
// 3. 作返回值:返回任意⼦类对象
public static Animal buyAnimal(String var){
if("狗".equals(var) ){
return new Dog("狗狗",1);
}else if("猫" .equals(var)){
return new Cat("猫猫", 1);
}else{
return null;
}
}
public static void main(String[] args) {
Animal cat = new Cat("元宝",2); // 1. 直接赋值:⼦类对象赋值给⽗类对象
Dog dog = new Dog("⼩七", 1);
eatFood(cat);
eatFood(dog);
Animal animal = buyAnimal("狗");
animal.eat();
animal = buyAnimal("猫");
animal.eat();
}
}
向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调⽤到⼦类特有的⽅法。
向下转型
将⼀个⼦类对象经过向上转型之后当成⽗类⽅法使⽤,再⽆法调⽤⼦类的⽅法,但有时候可能需要调⽤⼦类特有的⽅法,此时:将⽗类引⽤再还原为⼦类对象即可,即向下转换。

向下转型⽤的⽐较少,⽽且不安全,万⼀转换失败,运⾏时就会抛异常。Java中为了提⾼向下转型的安全性,引⼊了== instanceof== ,如果该表达式为true,则可以安全转换。