Java多态

先赞后看,养成习惯!!! ^ _ ^ ❤️ ❤️ ❤️
码字不易,大家的支持就是我坚持下去的动力,点赞后不要忘记关注我哦

个人主页:伯明翰java

文章专栏:JavaSE

如有错误,请您指正批评 ^ _ ^

1 多态的概念

多态就是不同类的对象对同一消息做出响应。即同一个接口,使用不同实例而执行不同的操作。多态分为编译时多态(重载)和运行时多态(重写)。它使程序具有良好的灵活性和扩展性。

1.1多态实现的条件

  1. 必须在继承体系下
  2. ⼦类必须要对⽗类中⽅法进⾏重写
  3. 通过⽗类的引⽤调⽤重写的⽅法
    多态体现:在代码运⾏时,当传递不同类对象时,会调⽤对应类中的⽅法。
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修饰,⾮构造⽅法

等的实现过程进⾏重新编写,返回值和形参都不能改变。即外壳不变,核⼼重写!重写的好处在于⼦类可以根据需要,定义特定于⾃⼰的⾏为。也就是说⼦类能够根据需要实现⽗类的⽅法。

  1. ⼦类在重写⽗类的⽅法时,⼀般必须与⽗类⽅法原型⼀致:返回值类型⽅法名 (参数列表)要完全⼀致。
  2. 被重写的⽅法返回值类型可以不同,但是必须是具有⽗⼦关系的。
  3. 访问权限不能⽐⽗类中被重写的⽅法的访问权限更低。例如:如果⽗类⽅法被public修饰,则⼦类中重写该⽅法就不能声明为protected。
  4. ⽗类被static、private修饰的⽅法、finaly修饰的方法、构造⽅法都不能被重写。
  5. 重写的⽅法,可以使⽤@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,则可以安全转换。

相关推荐
秋邱2 小时前
Java String家族全解析:String底层原理、常用方法与StringBuffer/StringBuilder区别
java·开发语言
糕......2 小时前
Java集合框架全解析
java·开发语言·网络·学习·list
okseekw2 小时前
深入理解Java注解:从自定义到实战应用
java·后端
你的冰西瓜2 小时前
C++中的forward_list容器详解
开发语言·c++·stl·list
LYOBOYI1232 小时前
qml的基本语法讲解
java·开发语言
tgethe2 小时前
==和equals的区别
java·开发语言·jvm
bbq粉刷匠2 小时前
Java二叉树基础提升
java·数据结构·算法
期待のcode2 小时前
java数据类型
java·开发语言
幽络源小助理2 小时前
简约个人发卡系统开源源码已测 – PHP源码
开发语言·php