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

Java抽象类与接口

在Java中,抽象类接口都是用于抽象化的概念,它们允许定义不完全的类,以便在子类中实现具体的行为。它们之间的区别在于抽象化的层级、设计目的以及具体的语法使用。

1. 抽象类 (Abstract Class)

  • 定义:使用abstract关键字声明,表示该类不能直接实例化,主要用来提供子类继承的通用属性和行为。

  • 特征

    • 可以包含抽象方法(没有方法体)和具体方法(有方法体)。
    • 可以包含成员变量,且可以声明为publicprotectedprivate等不同访问权限。
    • 可以有构造方法,用于子类初始化。
    • 支持字段和方法的继承机制,但一个类只能继承一个抽象类(因为Java是单继承的语言)。
  • 使用场景:当多个类有共同的属性和行为时,可以使用抽象类作为这些类的父类。例如,Animal可以是一个抽象类,DogCat继承Animal,并实现它的具体行为。

  • 示例

    abstract class Animal {
        String name;
        
        Animal(String name) {
            this.name = name;
        }
        
        abstract void makeSound(); // 抽象方法,没有实现
        
        void sleep() { // 具体方法,有实现
            System.out.println(name + " is sleeping.");
        }
    }
    
    class Dog extends Animal {
        Dog(String name) {
            super(name);
        }
        
        @Override
        void makeSound() {
            System.out.println(name + " barks.");
        }
    }
    

2. 接口 (Interface)

  • 定义:使用interface关键字定义,表示一组行为的契约或规范。

  • 特征

    • 只能包含抽象方法(Java 8 之后支持defaultstatic方法,有具体实现)。
    • 从Java 9开始支持私有方法,但只能在接口内部调用。
    • 不能包含成员变量,只能有public static final类型的常量。
    • 没有构造方法。
    • 一个类可以实现多个接口,从而实现多继承的效果。
  • 使用场景:当需要不同类之间有共同的行为规范,而不涉及具体的实现时可以使用接口。例如,Flyable接口可以被BirdAirplane实现,以表示飞行的能力。

  • 示例

    interface Flyable {
        void fly(); // 抽象方法
    }
    
    class Bird implements Flyable {
        @Override
        public void fly() {
            System.out.println("Bird is flying.");
        }
    }
    
    class Airplane implements Flyable {
        @Override
        public void fly() {
            System.out.println("Airplane is flying.");
        }
    }
    

3. 抽象类与接口的区别

特性抽象类接口
是否能有成员变量可以有普通成员变量只能有public static final常量
是否能有构造方法可以有构造方法不能有构造方法
方法实现可以有抽象和具体方法Java 8 之前只有抽象方法,Java 8 后可有默认方法
继承机制一个类只能继承一个抽象类一个类可以实现多个接口
访问修饰符可以有任何访问修饰符所有方法默认为public

4. 抽象类与接口的使用选择

  • 如果多个类具有相同的行为和属性,并且可以使用继承复用代码,适合使用抽象类。
  • 如果只希望定义方法规范而不涉及实现细节,并且支持多重实现,适合使用接口。

http://www.kler.cn/a/389118.html

相关文章:

  • 详解基于C#开发Windows API的SendMessage方法的鼠标键盘消息发送
  • react动态路由
  • vue2或vue3的name属性有什么作用?
  • ODOO学习笔记(8):模块化架构的优势
  • Linux相关习题-gcc-gdb-冯诺依曼
  • 网页web无插件播放器EasyPlayer.js点播播放器遇到视频地址播放不了的现象及措施
  • openresty入门教程:init_by_lua_block
  • ctfshow web入门黑盒测试web380-384
  • 每周算法2:数学+模拟+哈希表+栈+线性dp+贪心(简单)
  • 两个链表求并集、交集、差集
  • 微信小程序开发(二)登录流程
  • CMAKE 编译CUDA项目失败 “/usr/bin/nvcc“ is not able to compile a simple test program.
  • 通义千问API调用测试 (colab-python,vue)
  • 【机器学习】数学知识:指数
  • Android 延时操作的常用方法
  • Linux软件包管理
  • 分布式——BASE理论
  • 【harbor】离线安装2.9.0-arm64架构服务制作和升级部署
  • Java:JVM
  • 解决:使用EasyExcel导入Excel模板时出现数据导入不进去的问题
  • React前端框架:现代网页开发的基石(附带构建简单任务管理应用案例代码)
  • 栈(Stack)和队列(Deque、Queue)
  • 16.useForm
  • (附源码)django仓库管理系统-计算机毕设 30542
  • Python数据分析中的Pandas去重操作详解
  • mysql备份数据库及恢复