jav 抽象类,接口作为形参的使用场景

本文深入探讨了抽象类与接口在构造函数中的应用,通过具体实例展示了如何使用抽象类和接口作为参数进行构造,适用于架构设计与业务逻辑实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前几天有人问我在构造方法中传递一个形参,这个形参是要传递一个抽象类的引用,既然有人问到了,就表示还有人对此不太明白,今天周末没事,就瞎写一篇博客记录下,方便学习!

抽象类作为形式参数传递可以是构造函数,普通函数

1:抽象类作为形式参数传递给构造函数

代码体现

Person.java 测试抽象类

package cn.zgz.demo;
public abstract class Person {
    public String name;
    private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public abstract void study();
}

PersonInfo.java就一个无参的构造函数

public class PersonInfo {
   public PersonInfo(Person p){
 
   }
}

Test.java测试类

public class Test {
public static void main(String[] args) {
PersonInfo pInfo =new PersonInfo(new Person("王祖贤",24){
@Override
public void study() {
  System.out.println("我爱你");
}
});
}
}

我们在PersonInfo构造函数中传递了一个时Person的引用对象,而Person是一个抽象类,所以必须实现它的study()方法,这种传递方式很多地方用到在架构上比较多,平时代码这么写情况是比较少见的,至于普通方法也是一样的

2:接口作为形式参数传递给构造函数

代码体现

IListener.java 接口

package cn.zgz.inter;
/**
 * 接口 模拟android  button点击事件
 */
public interface IListener {
    void click();//点击方法
}

package cn.zgz.inter;

Button.java
/**
 * Button --模拟android中的Button按钮
 * 构造函数是一个接口
 */
public class Button {
    public Button(IListener listener){
    listener.click();
    }
}

Test.java测试类

package cn.zgz.inter;
/**
 * 测试类
 */
public class Test {
public static void main(String[] args) {
Button button = new Button(new IListener() {
@Override
public void click() {
System.out.println("我被点击了");
}
});
}
}

至于是传递抽象类还是接口要看具体的业务需求了,如果要传递的这个参数不仅对外提供了未实现的方法,而且还做了其他的初始化工作或者还有其他可调用的业务方法,那么就用抽象类,否则就用接口作为形参

<think>我们正在讨论Java接口抽象类的区别。根据用户的问题,我们需要详细解释这两者的区别。 注意:用户要求使用中文回答,并且按照系统级指令的要求,所有行内数学表达式使用$...$,独立公式使用$$...$$,但我们这里讨论的是Java编程概念,不太涉及数学公式,因此主要关注文本描述。 同时,根据指令,我们需要在回答中自然地添加引用标识。但注意,用户提供的引用[1]是关于抽象类接口区别的,我们可以参考它,并在适当的地方标注引用。 回答结构: 1. 首先给出基本定义的区别 2. 然后从语法、功能、使用场景等多个角度进行对比 3. 给出示例代码 4. 生成相关问题 注意:由于用户要求结构清晰,我们将分点说明。 开始回答:</think>### Java 接口抽象类的区别 在 Java 面向对象编程中,**接口(Interface)** 和 **抽象类(Abstract Class)** 都是实现抽象化的核心机制,但它们在设计理念和使用场景上存在本质区别: #### 一、核心概念差异 1. **抽象类** - 用 `abstract` 关键字声明,可包含**具体方法**(有实现)和**抽象方法**(无实现) - 本质是**不完全的类**,用于建立类层次结构的基类 - 示例: ```java abstract class Animal { abstract void sound(); // 抽象方法 void breathe() { // 具体方法 System.out.println("Breathing..."); } } ``` 2. **接口**(Java 8+) - 用 `interface` 声明,默认所有方法为 `public abstract`(可省略) - 可包含: - **抽象方法**(必须实现) - **默认方法**(`default` 修饰,有实现) - **静态方法**(`static` 修饰) - 本质是**行为契约**,定义对象能做什么 - 示例: ```java interface Swimmable { void swim(); // 抽象方法 default void floatOnWater() { // 默认方法 System.out.println("Floating..."); } } ``` #### 二、关键区别对比 | 特性 | 抽象类 | 接口 | |---------------------|----------------------------|-------------------------------| | **方法实现** | 可含具体方法和抽象方法 | Java 8 前只能有抽象方法 | | **变量** | 可含实例变量和常量 | 默认所有变量为 `public static final`(常量) | | **构造方法** | 可定义构造方法 | 不能有构造方法 | | **继承机制** | 单继承(extends 一个类) | 多实现(implements 多个接口) | | **访问修饰符** | 方法可任意访问修饰符 | 方法默认 `public` | | **设计目的** | 代码复用(IS-A 关系) | 行为规范(CAN-DO 关系) | | **状态维护** | 可维护对象状态 | 不能包含实例变量 | #### 三、使用场景 - **选择抽象类当**: - 需要共享代码或状态(如公共字段/方法) - 需要定义非 `public` 的受保护方法 - 扩展的类有明显 **IS-A** 关系(如 `Dog extends Animal`) - **选择接口当**: - 需要定义跨继承树的行为(如 `Plane implements Flyable`) - 需要多重行为继承 - 定义 API 契约(如 JDBC 的 `Connection` 接口) - 实现松耦合(如依赖注入) #### 四、演进变化(Java 8+) 1. **接口的增强** - 引入 `default` 方法:允许向后兼容性扩展 ```java interface Loggable { default void log(String msg) { System.out.println("LOG: " + msg); } } ``` - 引入 `static` 方法:提供工具方法(如 `Comparator.comparing()`) 2. **抽象类 vs 接口新平衡** | 能力 | 抽象类 | 接口Java 8+) | |--------------------|--------|----------------| | 方法实现 | ✓ | ✓(default) | | 静态方法 | ✓ | ✓ | | 构造方法 | ✓ | ✗ | | 实例字段 | ✓ | ✗ | | 多重继承 | ✗ | ✓ | > **设计原则**:优先使用接口定义行为,当需要状态共享或严格控制继承时再用抽象类[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值