【自学笔记】01Java基础-07面向对象基础-04接口与内部类详解

news2025/1/12 16:12:44

记录学习Java基础中有关接口类和内部类的知识。

1 接口

interface 关键字用于定义接口类,接口类是一系列方法的声明,一般只有方法的特征没有方法的实现,因此可以被不同的类接入实现,而这些实现可以具有不同的行为(功能)。

接口类似于抽象类(抽象类概念),其所有的方法默认是公开且抽象的(默认 public abstract 修饰),所有的成员变量默认是静态、不可变的常量public static final)。Java8开始,接口类也可以有非抽象的static静态方法和default方法,java9新增只能内部访问的private方法。

1.1 接口类的声明

  • 使用 interface 关键字来定义一个接口。接口中所有的成员都是public的,即使不显式声明。

public interface InterfaceClass {
     // 常量声明,默认public static final
	int CONSTANT_VARIABLE = 10;    
	 // 方法声明,默认是public abstract,可以省略
    void someMethod();
     // 默认方法default
     default void myDefaultMethod() {
     // ...
     }
     // 静态方法static
     static void myStaticMethod() {
     // ...
     }
}
  • 接口类方法

    • 接口中的所有方法默认具有 public abstract 修饰符(即使没有声明),实现了该接口的类必须实现所有方法。(java8新增的方法除外)
    • default方法:从java8开始,可以含default声明的方法,实现类可以直接使用或实现方法来覆写这类方法。
    • static静态方法:从java8开始,可以含static声明的方法,实现类可以直接类名.方法名()调用,但不能实现。
    • private私有方法:从java9开始,可以含private声明的方法,只能被本类其他默认方法或私有方法使用。
  • 静态常量

    • 接口中只能声明常量,无需显式声明 public static final,它们自动具有这些修饰符,并且必须初始化赋值。
      在这里插入图片描述

1.2 实现类的声明

  • 使用 implements 关键字来实现一个或多个接口,并提供接口中声明的所有抽象方法的实现。
  • 如果实现类不能实现接口的所有抽象方法,这个类需要声明为抽象类。>抽象类概念
public class ImplClass implements InterfaceClass_1,InterfaceClass_2 {
    @Override
    public void someMethod() {
        // 实现接口类中所有非静态的方法体
        // 接口类中default声明的方法可选实现
    }
}

1.3 接口的实现对比抽象类的继承

  • 类和类的关系:单继承。
  • 类和接口的关系:多实现。
  • 接口和接口的关系:多继承,一个接口可以同时继承多个接口。

1.4 接口多继承的作用

规范合并,整合多个接口为同一个接口,便于子类实现。

1.5 接口的注意事项

1、接口不能创建对象
2、一个类实现多个接口,多个接口的规范不能冲突
2、一个类实现多个接口,多个接口中有同样的静态方法不冲突。(使用接口.方法名()调用)
3、一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的。
4、一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
5、一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承。

1.6 接口的作用

  • 接口主要用于定义某种规范或者协议,确保不同类的对象之间能够共享相同的行为特征。
  • 它们在设计模式中广泛用于实现松耦合和面向接口编程,有助于提高代码的可重用性和可扩展性。

2 内部类

内部类就是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解成(宿主)。

public class People{
	// 内部类
	public class Heart{
	}
}

内部类的使用场景

  • 场景:当一个事物的内部,还有一个部分需要一个完整的结构进行描述时。

基本作用

  • 内部类通常可以方便访问外部类的成员,包括私有的成员。
  • 内部类提供了更好的封装性,内部类本身就可以用private ,protectecd等修饰,封装性可以做更多控制

2.1 内部类的分类

  • 静态内部类[了解]
  • 成员内部类(非静态内部类) [了解]
  • 局部内部类[了解]
  • 匿名内部类(重点)

2.2 静态内部类[了解]

什么是静态内部类?

  • 有static修饰,属于外部类本身。
  • 它的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别的类里面而已。
    在这里插入图片描述
    在这里插入图片描述

2.3 成员内部类[了解]

什么是成员内部类?

  • 无static修饰,属于外部类的对象。
  • JDK16之前,成员内部类中不能定义静态成员,JDK 16开始也可以定义静态成员了。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    答案:heartbeat, this.heartbeat, People.this.heartbeat

2.4 局部内部类[了解]

在这里插入图片描述

2.5 匿名内部类【重点】

  • 本质上是没有名字的局部内部类,同时也是一个对象,因此在创建时既声明又实例化。
  • 同时代表一个对象,其对象类型为当前new的那个类的子类。
  • 匿名内部类通常用在只使用一次且不需要单独定义一个类的情况下,简化代码编写。

1. 使用场景:

  • 当需要快速定义一个类来响应事件(如:Java Swing中的ActionListener)。
  • 当需要临时实现一个接口而不想为此创建单独的类文件时。

2. 定义与创建:
匿名内部类的格式如下:

//创建方式,new+类名()
new 外部类名() | 实现接口名() | 抽象类名(){
    // 实现父类方法或接口方法
    // 可以定义自己的成员变量和方法
};
//引用给对象
类名 对象名 = new 外部类名() | 实现接口名() | 抽象类名(){...}
Class c = new Class(){
	public void run(){
	}
};
c.run();

例如,实现一个Runnable接口的匿名内部类:

new Runnable() {
    @Override
    public void run() {
        System.out.println("Running in anonymous class");
    }
}.run();

或者继承一个抽象类并覆盖其方法:

abstract class Animal {
    abstract void sound();
}

new Animal() {
    @Override
    void sound() {
        System.out.println("Animal makes a sound");
    }
}.sound();

3. 特点:

  • 没有名称:匿名内部类由于没有名字,所以不能被引用,只能通过其父类或接口类型引用。
  • 局部作用域:匿名内部类可以访问包含它的外部类的所有成员(包括私有成员),同时也可以定义自己的局部变量,但这些变量必须是final或者事实上是final的。
  • 构造器限制:匿名内部类没有独立的构造函数,初始化过程通过构造代码块完成,即在类体中直接初始化成员变量。
  • 静态限制:匿名内部类不能包含静态成员、静态初始化块和静态方法,因为它们没有类名,无法直接指向静态成员。
  • 生命周期依赖外部类:匿名内部类的对象会隐式持有对外部类对象的引用,其生命周期受外部类实例的影响。

4. 注意事项:

  • 如果匿名内部类要访问外部方法的参数或者局部变量,那么这些变量必须是final或者实际上不可变的(尽管在Java 8之后,编译器允许省略final关键字,但仍要求实际行为不变)。

以下是一个实际案例,展示匿名内部类用于实现事件监听器:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

// 假设我们有一个GUI组件(如按钮)
javax.swing.JButton button = new javax.swing.JButton("Click me!");

// 按钮需要一个ActionListener来响应点击事件
// 而我们并不需要多次复用这个监听器,因此可以使用匿名内部类

// 通过匿名内部类创建并实例化ActionListener
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // 当按钮被点击时,执行的逻辑
        System.out.println("Button is clicked!");
    }
});

// 添加监听器到按钮上
frame.add(button);

// 显示GUI
// ...

在这个例子中,我们没有创建一个新的ActionListener子类,而是直接new一个临时的、未命名的类实现ActionListener接口。这样做的好处是能够将与按钮相关的操作逻辑紧密地封装在一起,同时简化代码编写。

另外,匿名内部类也可以用来扩展具体的类,例如在Android开发中,经常会有这样的场景:

public class MainActivity extends AppCompatActivity {

    private Button myButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myButton = findViewById(R.id.my_button);

        // 使用匿名内部类实现OnClickListener接口
        myButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "Button was clicked!", Toast.LENGTH_SHORT).show();
                // 在这里处理按钮点击事件
            }
        });
    }
}

在这个Android示例中,我们同样利用匿名内部类创建了一个OnClickListener对象,当myButton被点击时执行相应的逻辑。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《Training language models to follow instructions》论文解读--训练语言模型遵循人类反馈的指令

目录 1摘要 2介绍 方法及实验细节 3.1高层次方法论 3.2数据集 3.3任务 3.4人体数据收集 3.5模型 3.6评价 4 结果 4.1 API分布结果 4.2公共NLP数据集的结果 4.3定性结果 问题 1.什么是rm分数 更多资料 1摘要 使语言模型更大并不能使它们更好地遵循用户的意图。例…

C#学习教程一

VS2022 一:C#简介 基础: 全称:c sharp 面向对象 高级编程语言:(GC动态控制内存) C#、Java、Python... 低级编程语言:(经常与硬件打交道、内存、寄存器等) c/C++ 汇编... .net=dot net 过程: C/C++ 通过编译器转换成机器指令 C#通过编译器转换成IL中间语言…

怎么用 Excel 做出专业的 project 甘特图?10个步骤和60个模板

使用Excel来创建Project甘特图的步骤包括:1、基本设置和布局调整、2、数据输入和时间线配置、3、任务依赖性和进度跟踪、4、视觉效果优化、5、数据更新和维护、6、模板保存和共享。尤其突出基本设置和布局调整,它是构建一个清晰、有效的甘特图的基础。 甘…

【2023 - 探索】博0到博1,游戏新地图的探索日志

【2023 - 探索】博0到博1,游戏新地图的探索日志 写在最前面CSDN探索日志2023的探险 探索日志年终回顾探索 冒险回顾实习6月开始跟着老师做科研年中的一些其他事情9月开始上课开学后11月,读者互动 新年展望新年祝福 写在最前面 2023,我解锁了新…

Safari历史记录怎么恢复?掌握好这3个方法!

大家在使用Safari浏览器时难免会遇到一些问题,比如Safari历史记录误删除或意外丢失,想必这是一件很令人烦恼的事情。 那么,当苹果手机上的Safari历史记录不见时,我们该如何找回呢?safari历史记录怎么恢复?…

UTONMOS:探索元宇宙,开启未来游戏新篇章

在元宇宙的世界里,游戏不再只是消遣,而是一个全新的互动世界,等待你来探索! 逼真的虚拟现实技术,让你沉浸在充满想象力的游戏世界中,体验前所未有的刺激和乐趣。 与来自全球的玩家互动交流,结…

应用案例 | 使用Softing PROFIBUS Tester 5解决网络问题

PROFIBUS是在工业自动化领域里被广泛使用的现场总线协议,它具有高可靠性、低成本等优势,主要应用于制造业、能源、交通等领域。然而,随着时间的推移,PROFIBUS网络也不可避免地会出现一些组件老化的问题,从而对其性能和…

涛思数据获评北京市“专精特新”中小企业

众所周知,“专精特新”企业是国家引导中小企业增强自主创新能力和核心竞争力,不断提高中小企业发展质量和水平而实施的重大工程,旨在支持企业走专精特新发展之路,更好地促进企业高质量发展,也成为各领域产业链供应的关…

Project软件使用指南:六个关键功能助力项目成功

在项目管理的复杂世界中,Project软件提供了关键的解决方案。主要功能包括:1、任务和进度管理、2、资源分配、3、财务监控、4、风险评估、5、协作增强、6、报告和洞察力。特别是在任务和进度管理方面,Project软件通过动态时间表和任务跟踪工具…

CAN201 计网概念收集

Lecture 1 the theoretical basis for networking Network edge and core 地理覆盖范围:广WAN,城MAN,局LAN,个PAN 交换方式,电路,报文,分组 电路交换vs报文vs分组 Network performance pr…

vscode在node环境中如何调试

1.在vscode编辑器中,点击左侧的小图标。创建launch.js文件(这个文件创建好以后会在项目的.vscode文件下) 配置文件内容如下,我们只需要关注program字段,这是入口文件,写绝对路径就行 {// 使用 IntelliS…

C#调用WinAPI部分命令

C#是针对WIndows而生的,开发WIndows应用最快。然而想要让自己程序进阶,就不需深入Windows底层,WinAPI为我们提供了一把利刃。 目录 1、查找窗口句柄 2、查找窗口内子对象 3、指定窗口样式 4、指定窗口扩展样式 5、调整窗口大小Z轴(层叠) 6、获得窗口样式 7、向窗口…

Xcode15一个xcworkspace管理多个xcodeproj从零开始,一个主程序,多个子程序,一个主程序引用多个静态库

创建主程序:MainProject 目录结构: sandbox设置成NO:否则Xcode15不能运行 创建子程序 创建Framework 创建多个子程序后的目录结构 在主程序的Podfile中添加代码 # Uncomment the next line to define a global platform for your project pla…

Python库学习(十四):ORM框架-SQLAlchemy

1.介绍 SQLAlchemy 是一个用于 Python 的 SQL 工具和对象关系映射(ORM)库。它允许开发者通过 Python 代码而不是 SQL查询语言来操作数据库。SQLAlchemy 提供了一种灵活且强大的方式来与关系型数据库交互,支持多种数据库后端,如 P…

stable diffusion代码学习笔记

前言:本文没有太多公式推理,只有一些简单的公式,以及公式和代码的对应关系。本文仅做个人学习笔记,如有理解错误的地方,请指出。 资源 本文学习的代码;相关文献: Denoising Diffusion Probab…

手敲Mybatis(16章)-一级缓存功能实现

1.实现目的 这一节的目的主要是实现SqlSession级别的缓存,也就是一级缓存,首先看下图一,用户可以通过设置来进行是否开启一级缓存,不设置的化默认开启一级缓存,localCacheScopeSESSION为要设置一级缓存,lo…

【算法】基础算法001之双指针

👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.数组分块&#xf…

光伏项目如何建设和施工?

光伏项目现在已经成为能源行业最受欢迎、最有潜力的项目了,不仅仅可以减少温室气体的排放,也能够促进新能源和经济的发展。那么该如何建设和实施一个成功的光伏项目呢? 首先,选址是光伏项目成功的关键。理想的光伏项目应位于阳光充…

MySQL的三种存储引擎 InnoDB、MyISAM、Memory

InnoDB 1). 介绍 InnoDB是一种兼顾高可靠性和高性能的通用存储引擎,在 MySQL 5.5 之后,InnoDB是默认的MySQL 存储引擎。 2). 特点 DML操作遵循ACID模型,支持事务; 行级锁,提高并发访问性能; 支持外键F…

neo4j图数据库的简单操作记录

知识图谱文件导出 首先停止运行sudo neo4j stop然后导出数据库 导出格式为: 具体命令如下sudo neo4j-admin database dump --to-path/home/ neo4j最后重启sudo neo4j start知识图谱外观修改 在网页点击节点,选中一个表情后点击,可修改其颜…