Java抽象类

Java中的抽象类(Abstract Class)是一种特殊类型的类,它无法被实例化,只能被用作其他类的基础。抽象类用于定义具有共同特征和行为的一组相关类的共同结构和方法。抽象类可以包含抽象方法(没有具体实现的方法)和具体方法(有实际实现的方法)。

文章目录

    • 抽象类_abstract,不可被实例化:
      • 格式:
      • 但是可以创建抽象类的对象变量(object variable),但是这样一个变量只能引用子类的对象。
          • 好处:类似与方法重载,能够使用其特定的方法
    • 抽象方法_abstract,不可被实例化 ,子类必须实现
    • 抽象类的主要特点包括:
    • 6. 可以有构造方法: 这些构造方法在子类实例化时可以被调用【给子类对象赋值】,通常用于初始化抽象类中的字段。
    • 7.抽象类的子类要么重写抽象类中的所有抽象方法要么是抽象类:
      • 详细地讨论一下。
      • 举例子;

抽象类_abstract,不可被实例化:

作为他类的基类,用于定义共同的特征和行为,抽象类中的抽象方法未明确具体的方法
尽量将字段和方法(不论是否为抽象类)放在超类(不论是否是abstract)中

父类具有的是一般性,也可能抽象。
但从某种角度来说,其作为派生其他类的基类,而不是用到自己的想要的方式的特点实例。

如:

		Person|——————————————————————————————|								|Employee				Student

格式:

[修饰符]abstract class ClassName [extends 父类] [implements 接口列表]{成员内容}

但是可以创建抽象类的对象变量(object variable),但是这样一个变量只能引用子类的对象。

Person p =new Student();

p是抽象类型Person的一个变量,引用了非抽象子类Student的一个实例。

在这里插入图片描述
其中三角形和长方形的类中的实现了面积的方法是具体的,不再是抽象类了

好处:类似与方法重载,能够使用其特定的方法

抽象类可以用作一个通用的基类,它定义了一组通用的属性和方法。然后,具体的子类可以继承这个抽象类,并根据具体的需求来实现或扩展其中的方法。这种结构允许你在处理多个不同的子类时,使用抽象类类型的引用,从而获得多态性和灵活性的好处。
在这里插入图片描述

抽象方法_abstract,不可被实例化 ,子类必须实现

==其相当于子类实现本体的具体的方法的**占位符**==。
[修饰符]abstract 返回类型 方法名 ([参数列表][throws 异常列表]

抽象方法没有方法体,直接 分号;结束
含有抽象方法的类必须是抽象类,不能被实例化
抽象方法必须在子类中实现

如果抽象类中没有抽象方法,在子类在定义方法。就不能用父类引用子类中新增的内容了(和多态中类似,方法表

扩展抽象类:
(1)保留抽象类的部分或者所有抽象方法仍未定义,这样子类也必须标记为抽象类;

// 抽象类
abstract class Animal {abstract void makeSound();  // 抽象方法
}// 抽象子类,因为没有实现抽象方法
abstract class Bird extends Animal {// 这里没有提供对抽象方法 makeSound 的实现
}// 具体子类,实现了抽象方法,可以被实例化
class Dog extends Animal {@Overridevoid makeSound() {System.out.println("Dog barks");}
}// 具体子类,实现了抽象方法,可以被实例化
class Cat extends Animal {@Overridevoid makeSound() {System.out.println("Cat meows");}
}

Bird 是一个抽象子类,因为它继承了抽象父类 Animal,但没有提供对抽象方法 makeSound 的实现。而 Dog 和 Cat 都是具体子类,它们实现了抽象方法 makeSound,因此可以被实例化。

(2)定义全部方法,子类就不会抽象了。

// 抽象类
abstract class Shape {abstract double calculateArea();  // 抽象方法double calculatePerimeter() {return 0;  // 这里只是示范,具体计算逻辑需要实现类提供}
}// 具体子类,实现了抽象方法,可以被实例化
class Circle extends Shape {double radius;Circle(double radius) {this.radius = radius;}@Overridedouble calculateArea() {return Math.PI * radius * radius;}@Overridedouble calculatePerimeter() {return 2 * Math.PI * radius;}
}// 具体子类,实现了抽象方法,可以被实例化
class Rectangle extends Shape {double width;double height;Rectangle(double width, double height) {this.width = width;this.height = height;}@Overridedouble calculateArea() {return width * height;}@Overridedouble calculatePerimeter() {return 2 * (width + height);}
}

在这里插入图片描述

抽象类的主要特点包括:

强制子类必须按照特定的格式进行方法重写
抽象方法所在的类就是抽象类
  1. 不能被实例化:不能使用new关键字直接创建抽象类的实例。

  2. 可以包含抽象方法:抽象类可以定义抽象方法,这些方法没有实际的代码实现,只有方法签名。子类必须实现抽象类中的所有抽象方法。

     如果一个类包含至少一个抽象方法,那么这个类必须声明为抽象类。
    
  3. 可以包含具体方法:抽象类也可以包含具体的方法实现,这些方法在抽象类中有默认的实现,子类可以选择性地覆盖这些方法。

  4. 用于继承:其他类可以继承抽象类,并通过实现抽象方法来提供具体的实现。子类继承了抽象类的属性和方法。

  5. 用于多态:抽象类可以用于实现多态性,通过父类引用指向子类对象。

6. 可以有构造方法: 这些构造方法在子类实例化时可以被调用【给子类对象赋值】,通常用于初始化抽象类中的字段。

虽然抽象类本身不能被实例化,但是抽象类的构造方法仍然有其用途。抽象类的构造方法在以下几种情况下是有用的:

  1. 初始化抽象类的字段: 抽象类可以包含字段(成员变量),这些字段可以在构造方法中进行初始化。子类在实例化时会调用父类的构造方法来初始化父类的字段。

  2. 在子类构造方法中调用: 当子类实例化时,它的构造方法会隐式或显式地调用父类的构造方法,以确保父类的初始化逻辑得以执行。

  3. 构造方法的继承: 子类继承了父类的构造方法,尽管不能直接实例化抽象类,但子类在实例化时仍然需要调用适当的构造方法,以初始化继承自父类的字段。

  4. 调用抽象类中的方法: 构造方法也可以用于调用抽象类中的其他方法,无论这些方法是抽象的还是具体的。这些方法可能在子类的构造方法中执行特定的初始化逻辑。

尽管抽象类本身不能被实例化,但构造方法在创建其子类的对象时扮演着关键的角色。子类的构造方法在执行时会先调用父类的构造方法,以确保继承链中的初始化步骤得以完成。这有助于保持继承关系中的数据完整性和一致性。

7.抽象类的子类要么重写抽象类中的所有抽象方法要么是抽象类:

如果一个类继承了一个抽象类,并且不是抽象类本身,那么它要么必须提供实现来覆盖抽象类中的所有抽象方法,要么就必须自己声明为抽象类。如果子类没有提供实现,那么它也必须声明为抽象类。

以下是一个简单的Java抽象类的示例:

abstract class Animal {String name;Animal(String name) {this.name = name;}abstract void makeSound(); // 抽象方法,子类必须实现void eat() {System.out.println(name + " is eating."); // 具体方法}
}class Dog extends Animal {Dog(String name) {super(name);}void makeSound() {System.out.println(name + " barks.");}
}class Cat extends Animal {Cat(String name) {super(name);}void makeSound() {System.out.println(name + " meows.");}
}public class Main {public static void main(String[] args) {Dog dog = new Dog("Buddy");Cat cat = new Cat("Whiskers");dog.makeSound();cat.makeSound();dog.eat();cat.eat();}
}

在这个示例中,Animal是一个抽象类,它定义了一个抽象方法makeSound()和一个具体方法eat()DogCatAnimal的子类,它们必须实现makeSound()方法。在Main类中,通过多态性调用不同子类的方法。

抽象类的子类在继承抽象类时,通常必须实现抽象类中的所有抽象方法。抽象类是一种不能被实例化的类,它可以包含普通的方法和属性,也可以包含抽象方法。抽象方法是在抽象类中声明但没有提供具体实现的方法,它相当于一种约定,要求子类必须提供具体的实现。
······
当一个类继承一个抽象类时,如果该子类本身不是抽象类,那么它必须提供实现抽象类中所有抽象方法的具体实现。如果子类没有实现抽象类中的全部抽象方法,那么这个子类也必须被声明为抽象类。
·······
在面向对象编程中,抽象类和抽象方法用于定义一个通用的接口或者约定,以便子类可以继承并提供具体的实现。这种机制能够强制子类按照预期的方式来实现方法,从而保证代码的一致性和可维护性。

详细地讨论一下。

  1. 抽象方法(Abstract Methods): 抽象方法是在抽象类中声明的方法,它没有具体的实现代码,只有方法签名。子类必须实现抽象类中的抽象方法。这适用于在不同的子类中有不同的实现,而且你希望强制子类提供自己的实现。抽象方法通常用于定义基本操作,但这些操作在不同的子类中可能有不同的行为。

  2. 成员方法(Concrete Methods): 成员方法是在抽象类中有具体实现的方法。这些方法可以在抽象类中提供通用的、共享的实现,以避免在每个子类中重复编写相同的代码。子类可以选择性地覆盖这些方法,以适应特定的需求。成员方法通常用于实现通用的功能,这些功能在多个子类中都可以共享。

总之,你可以这样理解:

  • 使用抽象方法:当你希望在不同的子类中有不同的实现,而且这些实现在子类中是必需的时,你应该使用抽象方法。抽象方法强制子类提供自己的实现,确保基类的方法在子类中被正确覆盖。

  • 使用成员方法:当你有一些通用的、可复用的代码实现,可以在抽象类中提供默认的具体实现。子类可以直接继承这些方法,避免重复编写相同的代码。子类也可以选择性地覆盖这些方法,以适应特定需求。

需要注意的是,抽象类可以同时包含抽象方法和成员方法,这取决于你的设计需求。通过合理地使用抽象方法和成员方法,可以在代码中实现良好的组织和重用。

举例子;

package oop_useAbstractClass;// 定义一个抽象类 Shape,用于表示各种几何图形
public abstract class Shape {public int width; // 用于存储几何图形的宽度public int height; // 用于存储几何图形的高度// 构造方法,用于初始化宽度和高度public Shape(int width, int height) {this.width = width;this.height = height;}// 声明一个抽象方法 area(),用于计算图形的面积public abstract double calculateArea();
}
package oop_useAbstractClass;// 长方形类,继承自抽象类 Shape
public class Rectangle extends Shape {// 构造函数,接受长方形的长度和宽度作为参数public Rectangle(int length, int width) {// 调用父类的构造函数来初始化长度和宽度super(length, width);}// 重写父类中的抽象方法,计算长方形的面积@Overridepublic double calculateArea() {// 长方形的面积计算公式:长度 * 宽度return width * height;}
}
package oop_useAbstractClass;public class Triangle extends Shape {public Triangle(int width, int height) {super(width, height);}// 重写父类中的抽象方法,计算三角形面积的功能@Overridepublic double calculateArea() {return 0.5 * width * height;}
}
package oop_useAbstractClass;public class ShapeTest {public static void main(String[] args) {// 创建一个长方形对象并初始化其长和宽Rectangle rectangle = new Rectangle(5, 4);// 计算并输出长方形的面积System.out.println("长方形的面积为:" + rectangle.calculateArea());// 创建一个三角形对象并初始化其底边和高Triangle triangle = new Triangle(2, 5);// 计算并输出三角形的面积System.out.println("三角形的面积为:" + triangle.calculateArea());}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/104683.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VR防地质灾害安全教育:增强自然灾害知识,提高自我保护意识

VR防地质灾害安全教育系统是一种虚拟仿真技术,可以通过虚拟现实技术模拟地震、泥石流、滑坡等地质灾害的发生和应对过程,帮助人们提高应对突发自然灾害的能力。这种系统的优势在于可以增强自然灾害知识,提高自我保护意识,锻炼人们…

MyBatis分页插件PageHelper的使用及特殊字符的处理

目录 一、PageHelper简介 1.什么是分页 2.PageHelper是什么 3.使用PageHelper的优点 二、PageHelper插件的使用 原生limit查询 1. 导入pom依赖 2. Mybatis.cfg.xml 配置拦截器 3. 使用PageHelper进行分页 三、特殊字符的处理 1.SQL注入: 2.XML转义&#…

一、Kafka概述

目录 1.1 定义1.2 消息队列1、传统消息队列的应用场景2、消息队列的两种模式 1.3 Kafka的基础架构 1.1 定义 Kafka传 统定义:Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域。 K…

ACL2023 Prompt 相关文章速通 Part 1

Accepted Papers link: ACL2023 main conference accepted papers 文章目录 Accepted PapersPrompter: Zero-shot Adaptive Prefixes for Dialogue State Tracking Domain AdaptationQuery Refinement Prompts for Closed-Book Long-Form QAPrompting Language Models for Lin…

【Redis】什么是缓存击穿,如何预防缓存击穿?

【Redis】什么是缓存击穿,如何预防缓存击穿? 缓存击穿是指一个 Key 非常热点,大并发集中对这一个点进行访问,当这个Key 在失效的瞬间,持续的大并发就会穿破缓存,直接请求数据库。缓存击穿和缓存雪崩的区别…

基于FPGA视频接口之HDMI2.0编/解码

简介 为什么要特别说明HDMI的版本,是因为HDMI的版本众多,代表的HDMI速度同样不同,当前版本在HDMI2.1速度达到48Gbps,可以传输4K及以上图像,但我们当前还停留在1080P@60部分,且使用的芯片和硬件结构有很大差别,故将HDMI分为两个部分说明1080@60以下分辨率和4K以上分辨率(…

【WebSocket】前端使用WebSocket实时通信

目录 前言什么是WebSocketWebSocket的工作原理WebSocket与HTTP的关系HTTP建立持久化连接WebSocket类封装 前言 最近写项目,需要实现消息通知和实时聊天的功能,就去了解了一些关于websocket的知识,总结如下。 什么是WebSocket WebSocket 是一…

vscode C++17便捷配置教程(懒人版)

环境链接 以上是已经配置好的c17环境链接,直接下载解压即可(注意文件路径上不要带有中文) 下载解压之后按照msys64-mingw64-bin路径打开 然后单击该路径右方空白区域可直接复制路径 然后点击开始菜单搜索“环境变量“并打开(如…

SQL阶段性优化

😜作 者:是江迪呀✒️本文关键词:MySQL、SQL优化、阶段性优化☀️每日 一言:我们要把懦弱扼杀在摇篮中。 一、前言 我们在做系统的过程中,难免会遇到页面查询速度慢,性能差的问题,…

数据结构基础:P3-树(上)----编程作业02:List Leaves

本系列文章为浙江大学陈越、何钦铭数据结构学习笔记,系列文章链接如下: 数据结构(陈越、何钦铭)学习笔记 文章目录 一、题目描述二、整体思路与实现代码 一、题目描述 题目描述: 给定一棵树,按照从上到下、从左到右的顺序列出所有…

Compressor For Mac强大视频编辑工具 v4.6.5中文版

Compressor for Mac是苹果公司推出的一款视频压缩工具,可以将高清视频、4K视频、甚至是8K视频压缩成适合网络传输或存储的小文件。Compressor支持多种视频格式,包括H.264、HEVC、ProRes和AVC-Intra等,用户可以根据需要选择不同的压缩格式。 …

ModaHub魔搭社区:WinPlan经营大脑预算编制

目录 WinPlan经营大脑预算编制介绍 WinPlan经营大脑预算编制模版 WinPlan经营大脑预算模版管理 WinPlan经营大脑预算数据录入 WinPlan经营大脑预算编制介绍 预算编制时面向企业经营管理场景,创建各个业务单位的目标,包括销售目标、财务目标、人事目标等,实现各个业务单…

华为OD机试 - 最佳植树距离 - 二分查找(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、备注说明五、二分查找六、解题思路七、Java算法源码八、效果展示1、输入2、输出3、说明 一、题目描述 按照环保公司要求,小明需要在沙化严重的地区进行植树防沙工作,初步目标是种植一条直线的树带。 由于…

腾讯云和阿里云服务器折扣对比_看看哪家划算?

阿里云服务器和腾讯云服务器根据购买时长可以享受一定的优惠折扣,综合对比下来腾讯云折扣更低,阿腾云来对比下阿里云和腾讯云的云服务器根据购买时长可以享受的常规折扣对比: 目录 阿里云和腾讯云折扣对比 阿里云服务器常规折扣 腾讯云服…

CentOS KVM虚拟安装和开机启动

1. 配置系统 关闭SELinux setenforce 0持久化关闭配置 vi /etc/selinux/config2. 安装虚拟化软件 安装 KVM、QEMU等虚拟化软件。 yum install qemu-kvm qemu-img virt-manager libvirt virt-install virt-viewer 检查LVM模块是否已经加载 lsmod |grep kvm设置开机启动 s…

C语言:选择+编程(每日一练Day8)

目录 选择题: 题一: 题二: 题三: 题四: 题五: 编程题: 题一:字符个数统计 思路一: 题二:多数元素 思路一: 本人实力有限可能对一些…

JavaScript中的this关键字的作用,以及它如何确定其值

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ this关键字的作用⭐ this的值取决于执行上下文⭐ 示例⭐ 总结⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这…

1448. 统计二叉树中好节点的数目(C++题解)

1448. 统计二叉树中好节点的数目 给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。 「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。 示例 1: 输入:root [3,1,4,3,nu…

androidStudio或IDEA的通过gitBash打开插件

本人,一个资深的命令行,业余爱好者。常年直接vim,或者shell上服务器阅读代码。比较偏好使用GitBash来打开项目,进行git status,git diff,git add,commit等动作。 基于以上原因,本人开…

【Linux】【驱动】第一个相对完整的驱动编写

【Linux】【驱动】第一个相对完整的驱动编写 续1.驱动部分的代码2 app 代码3 操作相关的代码 续 这个章节会讲述去直接控制一个GPIO,高低电平。 因为linux不允许直接去操作寄存器,所以在操作寄存器的时候就需要使用到函数:ioremap 和iounma…