初识JAVA-面向对象的三大特征之多态

server/2025/1/15 11:32:57/

1. 重温面向对象

面向对象是一种解决问题的思想,它把计算机程序看作是各种对象组合起来的。每个对象都有自己的数据(属性)和行为(方法),主要依靠对象之间的交互来解决和实现问题。Java是一门纯面向对象的语言(Object Oriented Program,简称OOP)。

2. 多态

2.1 多态的概念

多态,简单来说就是多种形态,复杂点说就是不同对象去完成某个行为时产生不同的状态。

总的来说:同一件事情,发生在不同对象上,就会产生不同的结果。

2.2 多态实现条件

Java中实现多态,必须满足以下的条件,缺一不可:

1. 必须在继承的体系下才可以实现多态

2. 子类必须要对父类方法机械能重写

3. 通过父类的引用调用重写的方法

父类:

java">public class Pet{String name;String species;public Pet(String name, String species) {this.name = name;this.species = species;}public void eat(){System.out.println(name+"在进食");}
}

子类:

java">public class Cat extends Pet{public Cat(String name, String species) {super(name, species);}@Overridepublic void eat() {System.out.println(name+"吃冻干");}
}
java">public class Dog extends Pet{public Dog(String name, String species) {super(name, species);}@Overridepublic void eat() {System.out.println(name+"吃狗粮");}
}

进行测试:

java">public class TestPet {public static void eat(Pet pet){pet.eat();}public static void main(String[] args) {Cat cat=new Cat("咪咪","猫科动物");Dog dog=new Dog("旺旺","犬科动物");eat(cat);eat(dog);}
}

TestPet的代码时类调用者的编写

当类的调用者在编写eat这个方法时,参数类型为Pet(父类),此时在该类方法内部并不知道,也不关注当前的pet引用指向的那个子类的实例,pet这个引用调用的eat方法就可能有多种不同的表现(和pet引用的实例相关),这种行为就成为多态。

2.3 重写

重写(Override):也称为覆盖。重写是子类对父类非静态,非private修饰,非fianl修饰,非构造方法等的实现过程进行重新编写,返回值和形参都不能改变(外表不变,内心改变)。重写的好处在于子类可以根据需要,定义特定于自己的行为。

方法重写的规则:

1. 子类在重写父类方法时,必须与父类方法的方法名,参数列表要完全一致

2. 被重写的方法返回值类型可以不同,但是必须是具有父子关系的

3. 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为protected

4. 父类被static,private修饰的方法,构造函数都不能被重写

5. 重写的方法,可以使用@Override注解来显式指定

2.4 重写和重载的区别

方法重载是一个类的多态性表现,而方法重写式子类与父类的一种多态性表现

2.5 向上转型和向下转型

向上转型:实际就是创建一个子类对象,将其当作父类对象来使用

语法格式:父类类型 对象名=new 子类对象( )

java">Pet pet=new Dog("汪汪","犬科动物")

Pet是父类类型,但是可以引用一个子类对象,因为是从小范围到大范围的转换。

 使用场景:

1. 直接赋值

2. 方法传参

3. 方法返回

java">public class TestPet {//2.方法传参:形参为父类类型,可以接收子类对象public static void eat(Pet pet){pet.eat();}//3.作为返回值:返回任意子类对象public static Pet buyPet(String species){if("犬科动物".equals(species)){return new Dog("汪汪","犬科动物");}else if("猫科动物".equals(species)){return new Cat("咪咪","猫科动物");}else {return null;}}public static void main(String[] args) {//1.直接赋值:子类对象赋值给父类对象Pet cat=new Cat("咪咪","猫科动物");Pet dog=new Dog("旺旺","犬科动物");eat(cat);eat(dog);Pet pet=buyPet("犬科动物");pet.eat();}
}

向上转型的优点:让代码实现更加灵活

向上转型的缺点:不能调用子类特有的方法

将一个子类对象经过向上转型后当成父类方法使用,再也无法调用子类特有的方法,但有时候可能需要子类特有的方法,此时我们引入了向下转型。

向下转型:将父类引用还原成子类对象。

向下转型存在不安全的特点,例如下述代码:

java">public class Pet{String name;String species;public Pet(String name, String species) {this.name = name;this.species = species;}public void eat(){System.out.println(name+"在进食");}}
java">public class Dog extends Pet{public Dog(String name, String species) {super(name, species);}@Overridepublic void eat() {System.out.println(name+"吃狗粮");}public void bark(){System.out.println("汪汪汪!");}
}
java">public class Cat extends Pet{public Cat(String name, String species) {super(name, species);}@Overridepublic void eat() {System.out.println(name+"吃冻干");}public void mew(){System.out.println("喵喵喵!");}
}
java">public class TestPet {public static void eat(Pet pet){pet.eat();}public static void main(String[] args) {Cat cat=new Cat("咪咪","猫科动物");Dog dog=new Dog("旺旺","犬科动物");//向上转型Pet pet=cat;pet.eat();pet=dog;pet.eat();//此时pet指向的是dog,强制还原为cat,无法正常还原,抛出ClassCastExceptioncat= (Cat) pet;cat.mew();dog=(Dog) pet;dog.bark();}
}

 向下转型是不安全的,万一转型失败,运行时就会抛出异常。Java中为了提高向下转型的安全性,引入了instanceof,如果该表达式为true,则可以安全转型。

java">public class TestPet {public static void eat(Pet pet){pet.eat();}public static void main(String[] args) {Cat cat=new Cat("咪咪","猫科动物");Dog dog=new Dog("旺旺","犬科动物");//向上转型Pet pet=cat;pet.eat();pet=dog;pet.eat();if(pet instanceof Cat){cat= (Cat) pet;cat.mew();}if(pet instanceof Dog){dog=(Dog) pet;dog.bark();}}
}

2.6 多态的优缺点

多态的好处

1. 能够降低代码的圈复杂度,避免使用大量的if-else语句

圈复杂度是一种描述代码复杂程度的方式,一段代码平铺直叙,那么比较简单理解,如果有很多分支条件或者循环语句,就认为理解起来复杂。

2. 可拓展能力强

如果要新增一种行为,使用多态的方式代码改动的成本就比较低

多态的缺点:

1. 属性没有多态性

当父类和子类都有同名的属性时,通过弗雷德引用,只能引用父类自己的成员属性

2.构造方法没有多态性


http://www.ppmy.cn/server/158540.html

相关文章

【数据仓库】— 5分钟浅谈数据仓库(适合新手)从理论到实践

大家好,我是摇光~ 对于刚进入大数据领域的萌新,且想要在数据分析岗、数据运维岗、数据工程师这些岗位立足,了解数据仓库是必要的,接下来我尽量用通俗易懂的语言让大家了解到数据仓库。 在当今大数据盛行的时代,数据仓…

【网络云SRE运维开发】2025第3周-每日【2025/01/14】小测-【第13章ospf路由协议】理论和实操

文章目录 选择题(10道)理论题(5道)实操题(5道) 【网络云SRE运维开发】2025第3周-每日【2025/01/14】小测-【第12章ospf路由协议】理论和实操 选择题(10道) 在OSPF协议中&#xff0c…

Active Prompting with Chain-of-Thought for Large Language Models

题目 大型语言模型的思维链主动提示 论文地址:https://arxiv.org/abs/2302.12246 项目地址:https://github.com/shizhediao/active-prompt 摘要 大型语言模型(LLM)规模的不断扩大为各种需要推理的复杂任务带来了涌现能力,例如算术和常识推理…

Django创建项目速成

目录 1.创建项目 1.1 命令创建 1.2 pycharm创建 1.3 默认文件介绍 2.创建app 2.1 默认文件介绍 3.简单编写 3.1快速上手 确保app已经注册 编写url和视图函数的关系(创建关系) 编写视图函数 启动项目 4.模板语法 4.1 列表 4.2 字典 4.3 二…

基于YOLOv8与CGNet的鸟类智能识别系统 深度学习图像分类 鸟类目标检测与分类 图像特征提取 模型优化与应用 数据可视化(源码+指导+定制)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

【OJ刷题】同向双指针问题3

这里是阿川的博客,祝您变得更强 ✨ 个人主页:在线OJ的阿川 💖文章专栏:OJ刷题入门到进阶 🌏代码仓库: 写在开头 现在您看到的是我的结论或想法,但在这背后凝结了大量的思考、经验和讨论 目录 1…

Qt天气预报系统获取天气数据

Qt天气预报系统获取天气数据 1、获取天气数据1.1添加天气类头文件1.2定义今天和未来几天天气数据类1.3定义一个解析JSON数据的函数1.4在mainwindow中添加weatherData.h1.5创建今天天气数据和未来几天天气数据对象1.6添加parseJson定义1.7把解析JSON数据添加进去1.8添加错误1.9解…

【通信原理】为什么信号需要调制?

文章目录 1. 信号调制关键点:常见调制方式:应用:2. 信号如果不调制,直接发送会存在什么问题?1. 天线长度与波长的关系2. 低频信号的天线问题3. 高频信号的优势4. 调制的解决方案附:人耳能听到的声音的频率范围今天一个小朋友问我,信号为什么需要调制,直接发送不行吗,我…