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

Java从入门到“放弃”(精通)之旅——抽象类和接口⑨

Java从入门到“放弃”(精通)之旅🚀——抽象类和接口⑨

引言

在这里插入图片描述

在Java面向对象编程中,抽象类和接口是两个非常重要的概念。它们为代码提供了更高层次的抽象能力,是设计灵活、可扩展系统的关键工具。

🟦一、抽象类:不完全的蓝图

1.1 抽象类的基本概念

抽象类是一种特殊的类,它不能被实例化,只能被继承。抽象类存在的意义在于为子类提供一个通用的模板,其中可以包含具体实现的方法和需要子类实现的抽象方法。

// 抽象类示例:图形类
public abstract class Shape {// 抽象方法:没有方法体abstract public void draw();abstract void calcArea();// 普通方法和属性public double getArea() {return area;}protected double area; // 面积
}

在这里插入图片描述

1.2 抽象类的关键特性

  1. 不能直接实例化:尝试实例化抽象类会导致编译错误

    Shape shape = new Shape(); // 编译错误
    
  2. 抽象方法限制

    • 必须要使用 abstract 修饰
    • 不能是private(必须能被继承
    • 不能是final(必须能被子类重写
    • 不能是static(属于类而不属于实例
  3. 继承要求:子类必须实现所有抽象方法,除非子类也是抽象类

  4. 构造方法:抽象类可以有构造方法,用于初始化成员变量

1.3 抽象类的实际应用

// 矩形类实现
public class Rect extends Shape {private double length;private double width;Rect(double length, double width) {this.length = length;this.width = width;}@Overridepublic void draw() {System.out.println("矩形: length=" + length + " width=" + width);}@Overridepublic void calcArea() {area = length * width;}
}

📜二、接口:行为的契约

2.1 接口的基本概念

在这里插入图片描述通过上述例子可以看出:接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。

在Java中接口是一种引用数据类型,也是一种完全抽象的"纯规范",它定义了一组方法签名而没有具体实现。Java 8之后,接口可以包含默认方法和静态方法。

2.2 语法规则

接口的定义格式与定义类的格式基本相同,将class关键字换成 interface 关键字,就定义了一个接口。

public interface 接口名称{// 抽象方法public abstract void method1();   // public abstract 是固定搭配,可以不写public void method2();abstract void method3();void method4();// 注意:在接口中上述写法都是抽象方法,跟推荐方式4,代码更简洁
}

提示💡:

  1. 创建接口时, 接口的命名一般以大写字母 I 开头.
  2. 接口的命名一般使用 “形容词” 词性的单词.

代码示例:

// USB接口示例
public interface USB {void openDevice();  // 默认是public abstractvoid closeDevice();
}

2.3 接口的实现

// 鼠标类实现USB接口
public class Mouse implements USB {@Overridepublic void openDevice() {System.out.println("打开鼠标");}@Overridepublic void closeDevice() {System.out.println("关闭鼠标");}public void click() {System.out.println("鼠标点击");}
}

2.4 接口的核心特性和注意点❗

  1. 默认public abstract:接口方法默认是public abstract的
  2. 接口类型是一种引用类型:但是不能直接new接口的对象
  3. 变量默认public static final:接口中的变量默认是常量
  4. 不能有构造方法和静态代码块
  5. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
  6. 重写接口中方法时:不能使用默认的访问权限
  7. 多实现:一个类可以实现多个接口
  8. 接口继承:接口可以多继承其他接口

2.5 接口的多继承示例

interface IRunning {void run();
}interface ISwimming {void swim();
}// 接口多继承
interface IAmphibious extends IRunning, ISwimming {}// 青蛙类实现两栖接口
class Frog extends Animal implements IAmphibious {@Overridepublic void run() {System.out.println(this.name + "正在往前跳");}@Overridepublic void swim() {System.out.println(this.name + "正在蹬腿游泳");}
}

🗂️三、Clonable 接口和深拷贝

Java 中内置了一些很有用的接口, Clonable 就是其中之一.
Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常.

class Animal implements Cloneable {private String name;@Overridepublic Animal clone() {Animal o = null;try {o = (Animal)super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return o;}
}public class Test {public static void main(String[] args) {Animal animal = new Animal();Animal animal2 = animal.clone();System.out.println(animal == animal2);}
}// 输出结果
// false

浅拷贝 VS 深拷贝
Cloneable 拷贝出的对象是一份 “浅拷贝”
观察以下代码:

class Money {public double m = 99.99;
}class Person implements Cloneable{public Money money = new Money();@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}public class TestDemo3 {public static void main(String[] args) throws CloneNotSupportedException {Person person1 = new Person();Person person2 = (Person) person.clone();System.out.println("通过person2修改前的结果");System.out.println(person1.money.m);System.out.println(person2.money.m);person2.money.m = 13.6;System.out.println("通过person2修改后的结果");System.out.println(person1.money.m);System.out.println(person2.money.m);}
}// 执行结果
通过person2修改前的结果
99.99
99.99
通过person2修改后的结果
13.6
13.6

如上代码,我们可以看到,通过clone,我们只是拷贝了Person对象。但是Person对象中的Money对象,并没有拷贝。通过person2这个引用修改了m的值后,person1这个引用访问m的时候,值也发生了改变。这里就是发生了浅拷贝。

🆚四、抽象类与接口的对比

特性抽象类接口
实例化不能直接实例化不能直接实例化
方法实现可以有具体方法Java 8前只能有抽象方法
变量普通变量默认public static final常量
继承/实现单继承多实现
构造方法可以有不能有
访问修饰符各种权限默认public
设计理念“是什么”(is-a)关系“能做什么”(has-a)能力

图示:
在这里插入图片描述

🦸🏼五、Object类:所有类的超类

5.1 Object类概述

Object类是Java中所有类的默认父类,提供了以下重要方法:

  • toString(): 返回对象的字符串表示
  • equals(): 比较对象内容
  • hashCode(): 返回对象的哈希码
  • clone(): 创建并返回对象的拷贝

5.2 重要方法实现

equals方法重写示例:

@Override
public boolean equals(Object obj) {if (obj == null) return false;if (this == obj) return true;if (!(obj instanceof Person)) return false;Person person = (Person) obj;return this.name.equals(person.name) && this.age == person.age;
}

hashCode方法重写示例:

@Override
public int hashCode() {return Objects.hash(name, age);
}

📖六、总结与实践建议

  1. 抽象类使用场景

    • 需要为相关类提供公共代码
    • 需要声明非静态、非常量字段
    • 需要定义构造函数
  2. 接口使用场景

    • 需要定义行为契约
    • 需要多重继承行为
    • 需要定义API而不关心实现
  3. 设计原则

    • 优先使用接口而非抽象类(接口更灵活)
    • 当需要提供公共代码时再使用抽象类
    • 合理使用多态特性,编写更通用的代码

通过学习本文,相信您已经掌握了Java中抽象类和接口的核心概念与使用技巧。在实际开发中,灵活运用这些特性可以帮助您设计出更加优雅、可维护的面向对象程序。

在这里插入图片描述
JavaSE往期专栏

  • Java从入门到“放弃”(精通)之旅——启航①
  • Java从入门到“放弃”(精通)之旅——数据类型与变量②
  • Java从入门到“放弃”(精通)之旅——运算符③
  • Java从入门到“放弃”(精通)之旅——程序逻辑控制④
  • Java从入门到“放弃”(精通)之旅——方法的使用⑤
  • Java从入门到“放弃”(精通)之旅——数组的定义与使用⑥
  • Java从入门到“放弃”(精通)之旅——类和对象全面解析⑦
  • Java从入门到“放弃”(精通)之旅——继承与多态⑧
    在这里插入图片描述

相关文章:

  • Linux新手快速入门指南
  • XML内容解析成实体类
  • 【Python笔记 03 】运算符
  • 基于大疆行业无人机的特色解决方案-无线通信篇:基于蜂窝以及自组网MESH的无线通信C2链路
  • 一文详解Pytorch环境搭建:Mac电脑pip安装Pytorch开发环境
  • 空间数据工程——如何使用 Python 和 ArcPy 对 Vision Zero 多边形的值进行地理处理
  • Linux 安装pm2并全局可用
  • mysql数据库语言学习
  • 【简单学习】llamaindex环境搭建以及构建RAG
  • 深入理解依赖、Jar 包与 War 包:Java 开发基石探秘
  • 北京理工大学:光梳技术突破实现光场超高维调控
  • 基于PHP+MySQL实现(Web)单词助手网站
  • Embedding与向量数据库__0422
  • mysql too many open files
  • 数字空间与VR有什么关系?什么是数字空间?
  • TikTok X-Gnarly纯算分享
  • 针头式过滤器推荐
  • 游戏工作室为何要更换IP进行多开?工作室使用代理IP要注意什么?
  • CentOS7 环境配置
  • 【随机过程】柯尔莫哥洛夫微分方程总结
  • 目前中美未进行任何经贸谈判,外交部、商务部再次表明中方立场
  • 北大学者:过度依赖技术工具可能会削弱人类主动思考的能力
  • 夜读丨一条鱼的使命
  • 看正背面月壤、听火星上的声音,记者探营“中国航天日”科普展
  • 打造“旧书朋友圈”,“淘书乐”为旧书找“新朋友”
  • 陕西一批干部任职公示:西安市未央、雁塔、阎良区委书记拟调整