ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Java 抽象类与接口:从概念到实战的深度解析

Java 抽象类与接口:从概念到实战的深度解析 目录1. 什么是抽象类2. 抽象类的特点2.1 抽象方法2.2 实例代码演示步骤 1创建抽象类 Animal步骤 2创建子类 Fly鸟类继承 Animal步骤 3创建子类 Run哺乳动物继承 Animal步骤 4测试类3. 抽象类的实际应用场景4. 接口工程中的核心规范4.1 什么是接口4.2 接口与抽象类的区别4.3 为什么 Java 只允许单继承4.4 为什么接口不会出现菱形问题5. 接口的代码实践5.1 定义接口5.2 定义实现类5.3 测试类5.4 接口的多态应用6. 总结1. 什么是抽象类在 Java 中被abstract关键词修饰的类就叫做抽象类。2. 抽象类的特点不能直接实例化不能使用new关键词直接创建对象只能被子类继承使用。代码复用与解耦抽象类的功能和继承父类的作用相同——都是抽取公共代码实现代码复用从而减少耦合提高工程效率。2.1 抽象方法抽象类有两个相关概念其中一个是抽象方法只有方法的声明只有方法名没有方法体没有方法的具体实现逻辑。特点是使用abstract关键词修饰。只能存在于抽象类、接口中。抽象类中可以有非抽象成员不使用abstract关键词修饰的方法、属性。2.2 实例代码演示下面通过一个完整的例子来理解抽象类的使用步骤 1创建抽象类 Animal// Animal.java public abstract class Animal { // 抽象方法只有声明没有方法体 public abstract void move(); // 非抽象方法 public void eat() { System.out.println(动物正在进食...); } }步骤 2创建子类 Fly鸟类继承 Animal// Fly.java public class Fly extends Animal { // 必须实现父类的抽象方法 Override public void move() { System.out.println(鸟儿在天空中飞翔); } }步骤 3创建子类 Run哺乳动物继承 Animal// Run.java public class Run extends Animal { Override public void move() { System.out.println(哺乳动物在地上奔跑); } }步骤 4测试类// Test.java public class Test { public static void main(String[] args) { // 创建子类对象 Animal bird new Fly(); Animal mammal new Run(); // 调用方法 bird.move(); // 输出鸟儿在天空中飞翔 bird.eat(); // 输出动物正在进食... mammal.move(); // 输出哺乳动物在地上奔跑 mammal.eat(); // 输出动物正在进食... } }从测试结果可以看到抽象类的使用和普通父类方法重写没有本质区别但它强制子类必须实现特定的抽象方法从而保证了代码的规范性。3. 抽象类的实际应用场景正如老师所说“今天我讲完抽象类之后除了你们 25 级软工的大二还要再学习一遍 JavaSE 的小部分知识以外你这一辈子再也不会碰到抽象类了。除非你很有想法主动找一些工程源码或者看 Java 自带的 API”这说明了抽象类在实际工程开发中使用频率相对较低更多出现在教学和底层框架设计中。但理解抽象类对于掌握面向对象编程思想至关重要。4. 接口工程中的核心规范如果说抽象类在实际工程中用得很少那么接口则是每个计算机从业者都必须掌握的概念。老师强调“你只要是从事和计算机相关的行业不管是前后端、全栈开发、测试、AI百分之一千会用到接口。”4.1 什么是接口让我们通过一个生动的故事来理解接口的作用有两家开发数据库的公司他们垄断了全球所有数据库的市场。A 数据库公司开发了两种查询数据库的方法分别是selectAll、selectNameById公司 B 也开发了两种查询方法分别是findAll、findNameById。大壮是 A 企业的员工他的女朋友也在 A 企业。大壮女朋友现在和大壮闹分手她说“我再也不想你出现在我的生活里”。那么大壮只能从 A 公司跳槽到 B 公司可是他只会用 A 公司给出的两个方法不会用 B 公司给出的方法他不知道 B 公司给出的这些方法是干什么的哪怕这两个方法的实现逻辑是相同的。了解到这个情况AB 两家公司的老总就给出了一个解决方案既然我们这两家公司的查询方案都相同为什么不统一一下查询方法的签名呢于是两家公司将两种查询方法统一命名为selectAll、selectNameById。这就是接口的核心作用用来规范和管理工程逻辑的命名。在实际开发中我们先规定需要实现的方法以及这个方法是用来做什么的定义接口然后再来定义实现类来完成方法的具体实现逻辑方法体。4.2 接口与抽象类的区别听着是不是和抽象类差不多那么抽象类和接口的区别在哪呢对比维度抽象类接口设计目的代码复用抽取公共代码规范行为定义契约使用时机在项目进展过程中抽取重复代码在项目开展之前规定需要用的方法继承/实现Java 只允许单继承一个类可以实现多个接口方法实现可以有具体方法实现Java 8 前只能是抽象方法4.3 为什么 Java 只允许单继承这是为了防止菱形问题Diamond Problemclass A { public void eat() { System.out.println(A eat); } } class B extends A { Override public void eat() { System.out.println(B eat); } } class C extends A { Override public void eat() { System.out.println(C eat); } } // 如果允许多继承会出现问题 // class D extends B, C { } // D 调用 eat() 时编译器不知道该执行 B 的还是 C 的版本产生歧义。4.4 为什么接口不会出现菱形问题因为接口里默认都是抽象方法没有方法体哪怕多个接口有同名抽象方法最终都由实现类自己重写一遍实现类说了算不会产生冲突。5. 接口的代码实践5.1 定义接口// Function.java public interface Function { // 抽象方法默认就是 public abstract void selectAll(); void selectNameById(int id); }5.2 定义实现类建议将接口的实现类命名为接口名 Impl// FunctionImpl.java public class FunctionImpl implements Function { Override public void selectAll() { System.out.println(查询所有数据); } Override public void selectNameById(int id) { System.out.println(根据ID查询名称ID id); } }5.3 测试类// TestInterface.java public class TestInterface { public static void main(String[] args) { // 接口不能使用 new 创建对象必须使用实现类的构造方法 Function func new FunctionImpl(); // 调用接口方法 func.selectAll(); // 输出查询所有数据 func.selectNameById(1001); // 输出根据ID查询名称ID1001 } }5.4 接口的多态应用既然可以使用接口的引用类型创建实际对象那么就可以用到多态// 定义第二个接口 public interface Function2 { void customMethod(); } // 实现类实现多个接口 public class MultiFunctionImpl implements Function, Function2 { Override public void selectAll() { System.out.println(实现 selectAll); } Override public void selectNameById(int id) { System.out.println(实现 selectNameByIdID id); } Override public void customMethod() { System.out.println(Function2 的自定义方法); } } // 测试多态 public class TestPolymorphism { public static void main(String[] args) { Function func1 new MultiFunctionImpl(); Function2 func2 new MultiFunctionImpl(); // 接口约束了对象能够使用的方法 func1.selectAll(); // 正确 // func1.customMethod(); // 编译错误Function 接口中没有 customMethod 方法 func2.customMethod(); // 正确 // func2.selectAll(); // 编译错误Function2 接口中没有 selectAll 方法 } }6. 总结抽象类和接口是 Java 面向对象编程中两个重要的概念它们的核心区别在于设计目的不同抽象类侧重于代码复用接口侧重于行为规范。使用场景不同抽象类用于有共同特征的类层次结构接口用于定义跨不同类别的行为契约。继承机制不同Java 只支持单继承避免菱形问题但支持多接口实现。方法实现不同抽象类可以有具体实现接口在 Java 8 前只能是抽象方法。在实际工程开发中接口的使用频率远高于抽象类。理解它们的区别和适用场景对于编写高质量、可维护的 Java 代码至关重要。
返回列表