当前位置: 首页 > news >正文

Java-面向对象-多态和抽象类

目录

什么是多态?

多态的优点

多态存在的三个必要条件

虚函数

重写

多态的实现方式

什么是抽象类?

继承抽象类

实现抽象方法

抽象类总结


什么是多态?

多态就是一个行为具有多种不同的表现形式

举例:

我们按下 F1 键这个动作:

  • 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档

  • 如果当前在 Word 下弹出的就是 Word 帮助

  • 在 Windows 下弹出的就是 Windows 帮助和支持

多态的优点

  • 消除类型之间的耦合性
  • 灵活性(接口性)
  • 可替换性
  • 可扩充性
  • 简化性

多态存在的三个必要条件

  • 继承
  • 重写
  • 父类引用执行子类对象(核心)

演示:

class Animal {// 定义一个方法,让动物发出声音public void makeSound() {System.out.println("动物发出声音");}
}class Dog extends Animal {// 覆盖父类的 makeSound 方法@Overridepublic void makeSound() {System.out.println("汪汪汪");}
}class Cat extends Animal {// 覆盖父类的 makeSound 方法@Overridepublic void makeSound() {System.out.println("喵喵喵");}
}class Bird extends Animal {// 覆盖父类的 makeSound 方法@Overridepublic void makeSound() {System.out.println("叽叽喳喳");}
}public class Zoo {public static void main(String[] args) {// 创建一个 Animal 类型的数组,用来存储不同类型的动物Animal[] animals = new Animal[3];// 将不同类型的动物对象赋值给数组animals[0] = new Dog();animals[1] = new Cat();animals[2] = new Bird();// 遍历数组,调用每个动物的 makeSound 方法for (Animal animal : animals) {animal.makeSound();}}
}

通过这个实例是想说明,多态的核心是:父类引用执行子类对象

虚函数

我们可以把这段代码想象成一个动物园管理员(Zoo 类中的 main 方法)在管理动物。管理员有一个笼子(Animal 类型的数组),笼子里可以放各种动物(DogCatBird)。管理员不需要知道笼子里具体是什么动物,只需要让每个动物发出自己的声音(调用 makeSound 方法)。 

虚函数

Java中的方法默认就是“虚函数”,即支持动态绑定(也称为动态多态)

演示:

class Menu {// 定义一个方法,表示品尝菜品public void taste() {System.out.println("品尝一道普通的菜品");}
}class ChefA extends Menu {// 覆盖父类的 taste 方法@Overridepublic void taste() {System.out.println("品尝一道由厨师A烹饪的美味菜品");}
}class ChefB extends Menu {// 覆盖父类的 taste 方法@Overridepublic void taste() {System.out.println("品尝一道由厨师B烹饪的特色菜品");}
}public class Restaurant {public static void main(String[] args) {// 创建一个 Menu 类型的引用,指向不同的厨师烹饪的菜品Menu menu1 = new ChefA();Menu menu2 = new ChefB();// 顾客品尝菜品menu1.taste(); // 输出:品尝一道由厨师A烹饪的美味菜品menu2.taste(); // 输出:品尝一道由厨师B烹饪的特色菜品}
}

这意味着方法的调用是在运行时根据对象的实际类型来决定的,而不是根据引用的类型。这正是多态的核心所在。

重写

在Java中,当一个父类类型的引用指向一个子类对象时,调用方法时会根据对象的实际类型来决定调用哪个方法如果没有重写,子类将继承父类的方法,而不会提供自己的实现。这样,动态绑定就失去了意义,因为调用的始终是父类的方法

多态的实现方式

  • 重写/重载
  • 接口
  • 抽行类和抽象方法

什么是抽象类?

在Java中,抽象类(Abstract Class)是一种特殊的类,它不能被直接实例化,但可以作为其他类的父类。这里可能有同学问,既然抽象类都不能被实例化,那存在抽象类的意义是什么呢?

  • 抽象类的定义

抽象类是通过关键字 abstract 修饰的类,它不能被实例化,但可以包含抽象方法(没有具体实现的方法)和具体方法(有具体实现的方法)抽象方法也必须用 abstract 关键字修饰,且没有具体的方法体。

abstract class Animal {// 抽象方法,没有具体实现public abstract void makeSound();// 具体方法,有具体实现public void eat() {System.out.println("动物吃东西");}
}
  • 抽象类存在的意义

抽象类的主要作用是定义一组通用的接口和行为规范,这些规范可以被多个子类共享和实现。通过抽象类,我们可以定义一些通用的方法签名(抽象方法),而具体的实现细节则由子类提供

演示:

假设你有一个汽车工厂,工厂生产各种类型的汽车,比如轿车、卡车和摩托车。虽然这些汽车的类型不同,但它们都有共同的行为,比如“启动”和“停止”。抽象类就像汽车工厂的蓝图,定义了所有汽车必须具备的基本行为,而具体的实现则由每种汽车来完成

abstract class Vehicle {// 抽象方法,定义所有车辆必须具备的行为public abstract void start();public abstract void stop();
}class Car extends Vehicle {@Overridepublic void start() {System.out.println("轿车启动");}@Overridepublic void stop() {System.out.println("轿车停止");}
}class Truck extends Vehicle {@Overridepublic void start() {System.out.println("卡车启动");}@Overridepublic void stop() {System.out.println("卡车停止");}
}

继承抽象类

要继承抽象类,需要使用 extends 关键字。继承抽象类的子类有两种情况:

  • 子类是抽象类

子类可以不实现父类中的所有抽象方法,但子类本身也必须被声明为抽象类

abstract class Animal {// 抽象方法,没有具体实现public abstract void makeSound();// 具体方法,有具体实现public void eat() {System.out.println("动物吃东西");}
}abstract class Mammal extends Animal {// 子类继承了抽象类 Animal,但没有实现 makeSound 方法// 因此,子类 Mammal 也必须被声明为抽象类
}
  • 子类是非抽象类

子类必须实现父类中的所有抽象方法

abstract class Animal {// 抽象方法,没有具体实现public abstract void makeSound();// 具体方法,有具体实现public void eat() {System.out.println("动物吃东西");}
}class Dog extends Animal {// 实现父类中的抽象方法@Overridepublic void makeSound() {System.out.println("汪汪汪");}
}

实现抽象方法

实现抽象方法时,需要使用 @Override 注解(可选,但推荐使用)来覆盖父类的方法。

abstract class Animal {// 抽象方法,没有具体实现public abstract void makeSound();// 具体方法,有具体实现public void eat() {System.out.println("动物吃东西");}
}class Cat extends Animal {// 实现父类中的抽象方法@Overridepublic void makeSound() {System.out.println("喵喵喵");}
}

一旦子类实现了父类中的所有抽象方法,就可以被实例化,并且使用:

public class Zoo {public static void main(String[] args) {// 创建 Dog 类的实例Dog dog = new Dog();dog.makeSound(); // 输出:汪汪汪dog.eat();       // 输出:动物吃东西// 创建 Cat 类的实例Cat cat = new Cat();cat.makeSound(); // 输出:喵喵喵cat.eat();       // 输出:动物吃东西}
}

抽象类总结

  1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
  2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
  4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
  5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

http://www.mrgr.cn/news/96191.html

相关文章:

  • 【进阶】vscode 中使用 cmake 编译调试 C++ 工程
  • NDK CMake工程中引入其他C++三方库
  • Redis和三大消息队列
  • STM32F103_LL库+寄存器学习笔记09 - DMA串口接收与DMA串口发送,串口接收空闲中断
  • VxKex无法通过快捷方式启动程序
  • gogs私服搭建
  • ZeroMQ介绍及如何交叉编译在嵌入式Linux下使用
  • ESP32-CAM在PlatformIO IDE里实现OTA的几个小TIPS
  • 骨密度以及骨密度测量,测量方案,意义;提高;实现方案
  • jmeter 镜像构建
  • C语言学习关键笔记
  • 数据结构C语言练习(顺序表)
  • 论文阅读笔记:Denoising Diffusion Implicit Models
  • nara wpe去混响学习笔记
  • 力扣刷题第一遍
  • Microi吾码界面设计引擎之基础组件用法大全【内置组件篇·中】
  • Leetcode算法方法总结
  • 生成器的应用 async与await实现
  • 【leetcode hot 100 347】前 K 个高频元素
  • centos8上实现lvs集群负载均衡nat模式