面向对象【内部类】

news2024/11/16 20:28:51

请添加图片描述

什么是内部类

将一个类 A 定义在另一个类 B 里面,里面的那个类 A 就称为内部类(InnerClass),类 B 则称为外部类(OuterClass)

为什么要声明内部类

具体来说,当一个事物 A 的内部,还有一个部分需要一个完整的结构 B 进行描述,而这个内部的完整的结构 B 又只为外部事物 A 提供服务,不在其他地方单独使用,那么整个内部的完整结构 B 最好使用内部类。
总的来说,遵循高内聚、低耦合的面向对象开发原则。

成员内部类

如果成员内部类中不使用外部类的非静态成员,那么通常将内部类声明为静态
内部类,否则声明为非静态内部类。

成员内部类作为类的成员的角色:

– 和外部类不同,Inner class 还可以声明为 private 或 protected;
– 可以调用外部类的结构。(注意:在静态内部类中不能使用外部类的非静态成员)
– Inner class 可以声明为 static 的,但此时就不能再使用外层类的非 static 的成员变量;

成员内部类作为类的角色:

– 可以在内部定义属性、方法、构造器等结构
– 可以继承自己的想要继承的父类,实现自己想要实现的父接口们,和外部类的父类和父接口无关
– 可以声明为 abstract 类 ,因此可以被其它的内部类继承
– 可以声明为 final 的,表示不能被继承
– 编译以后生成 OuterClass$InnerClass.class 字节码文件(也适用于局部内部类)

注意点:

  • 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
  • 成员内部类可以直接使用外部类的所有成员,包括私有的数据
  • 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的
public class TestMemberInnerClass {
 public static void main(String[] args) {
 
 //创建静态内部类实例,并调用方法
 Outer.StaticInner inner = new Outer.StaticInner();
 inner.inFun();
 
 //调用静态内部类静态方法
 Outer.StaticInner.inMethod();
 System.out.println("*****************************");
 
 //创建非静态内部类实例(方式 1),并调用方法
 Outer outer = new Outer();
 Outer.NoStaticInner inner1 = outer.new NoStaticInner();
 inner1.inFun();
 
 //创建非静态内部类实例(方式 2)
 Outer.NoStaticInner inner2 = outer.getNoStaticInner();
 inner1.inFun();
 }
}
class Outer{
 private static String a = "外部类的静态 a";
 private static String b = "外部类的静态 b";
 private String c = "外部类对象的非静态 c";
 private String d = "外部类对象的非静态 d";
 
 static class StaticInner{
	 private static String a ="静态内部类的静态 a";
	 private String c = "静态内部类对象的非静态 c";
	 
 public static void inMethod(){
	 System.out.println("Inner.a = " + a);
	 System.out.println("Outer.a = " + Outer.a);
	 System.out.println("b = " + b);
 }
 
 public void inFun(){
	 System.out.println("Inner.inFun");
	 System.out.println("Outer.a = " + Outer.a);
	 System.out.println("Inner.a = " + a);
	 System.out.println("b = " + b);
	 System.out.println("c = " + c);
	// System.out.println("d = " + d);//不能访问外部类的非静态成员
 }
 }
 
 class NoStaticInner{
 
	 private String a = "非静态内部类对象的非静态 a";
	 private String c = "非静态内部类对象的非静态 c";
	 
 public void inFun(){
	 System.out.println("NoStaticInner.inFun");
	 System.out.println("Outer.a = " + Outer.a);
	 System.out.println("a = " + a);
	 System.out.println("b = " + b);
	 System.out.println("Outer.c = " + Outer.this.c);
	 System.out.println("c = " + c);
	 System.out.println("d = " + d);
	 }
 }
 public NoStaticInner getNoStaticInner(){
	 return new NoStaticInner();
 }
}

局部内部类

非匿名局部内部类

编译后有自己的独立的字节码文件,只不过在内部类名前面冠以外部类名、$符号、编号。
– 这里有编号是因为同一个外部类中,不同的方法中存在相同名称的局部内部类

  • 和成员内部类不同的是,它前面不能有权限修饰符等
  • 局部内部类如同局部变量一样,有作用域
  • 局部内部类中是否能访问外部类的非静态的成员,取决于所在的方法
public class TestLocalInner {
 public static void main(String[] args) {
	 Outer.outMethod();
	 System.out.println("-------------------");
	 Outer out = new Outer();
	 out.outTest();
	 System.out.println("-------------------");
	 Runner runner = Outer.getRunner();
	 runner.run();
 }
}
class Outer{
	 public static void outMethod(){
		 System.out.println("Outer.outMethod");
		 final String c = "局部变量 c";
	 class Inner{
		 public void inMethod(){
		 System.out.println("Inner.inMethod");
		 System.out.println(c);
	 }
 }
 Inner in = new Inner();
 	in.inMethod();
 }
 public void outTest(){
	 class Inner{
		 public void inMethod1(){
		 System.out.println("Inner.inMethod1");
	 }
 }
	 Inner in = new Inner();
	 in.inMethod1();
 }
 public static Runner getRunner(){
	 class LocalRunner implements Runner{
	 
	 @Override
	 public void run() {
		 System.out.println("LocalRunner.run");
	 }
 }
 return new LocalRunner();
 }
}
interface Runner{
 void run();
}

匿名内部类

因为考虑到这个子类或实现类是一次性的,那么我们“费尽心机”的给它取名字,就显得多余。那么我们完全可以使用匿名内部类的方式来实现,避免给类命名的问题。


举例 1:使用匿名内部类的对象直接调用方法:

interface A{
void a();
}
public class Test{
 public static void main(String[] args){
 new A(){
 
@Override
public void a() {
	System.out.println("aaaa");
}
 }.a();
 }
}

举例 2:通过父类或父接口的变量多态引用匿名内部类的对象

interface A{
	void a();
}
public class Test{
 public static void main(String[] args){
 A obj = new A(){
@Override
public void a() {
	System.out.println("aaaa");
}
 };
 obj.a();
 }
}

举例 3:匿名内部类的对象作为实参

interface A{
	void method();
}
public class Test{
 public static void test(A a){
	 a.method();
 }
 
 public static void main(String[] args){
 test(new A(){
	@Override
	public void method() {
		System.out.println("aaaa");
	}
 });
 } 
}

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

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

相关文章

基于SpringBoot的后勤管理系统【附源码】

后勤管理系统开发说明 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myecli…

LLM 面试知识点——模型基础知识

1、主流架构 目前LLM(Large Language Model)主流结构包括三种范式,分别为Encoder-Decoder、Causal Decoder、Prefix Decode。对应的网络整体结构和Attention掩码如下图。 、 各自特点、优缺点如下: 1)Encoder-Decoder 结构特点:输入双向注意力,输出单向注意力。 代表…

【C语言】linux内核pci_save_state

一、中文注释 //include\linux\pci.h /* 电源管理相关的例程 */ int pci_save_state(struct pci_dev *dev);//drivers\pci\pci.c /*** pci_save_state - 在挂起前保存PCI设备的配置空间* dev: - 我们正在处理的PCI设备*/ int pci_save_state(struct pci_dev *dev) {int i;/* X…

HTML + CSS 核心知识点- 定位

简述: 补充固定定位也会脱离文档流、不会占据原先位置 1、什么是文档流 文档流是指HTML文档中元素排列的规律和顺序。在网页中,元素按照其在HTML文档中出现的顺序依次排列,这种排列方式被称为文档流。文档流决定了元素在页面上的位置和互相之…

基于Spring Boot的美食分享系统设计与实现

摘 要 美食分享管理,其工作流程繁杂、多样、管理复杂与设备维护繁琐。而计算机已完全能够胜任美食分享管理工作,而且更加准确、方便、快捷、高效、清晰、透明,它完全可以克服以上所述的不足之处。这将给查询信息和管理带来很大的方便&#x…

PHP<=7.4.21 Development Server源码泄露漏洞 例题

打开题目 dirsearch扫描发现存在shell.php 非预期解 访问shell.php&#xff0c;往下翻直接就看到了flag.. 正常解法 访问shell.php 看见php的版本是7.3.33 我们知道 PHP<7.4.21时通过php -S开起的WEB服务器存在源码泄露漏洞&#xff0c;可以将PHP文件作为静态文件直接输…

万界星空科技WMS仓储管理包含哪些具体内容?

wms仓库管理是通过入库业务、出库业务、仓库调拨、库存调拨和虚仓管理等功能&#xff0c;综合批次管理、物料对应、库存盘点、质检管理、虚仓管理和即时库存管理等功能综合运用的管理系统&#xff0c;有效控制并跟踪仓库业务的物流和成本管理全过程&#xff0c;实现完善的企业仓…

面试笔记——Redis(缓存击穿、缓存雪崩)

缓存击穿 缓存击穿&#xff08;Cache Breakdown&#xff09;&#xff1a; 当某个缓存键的缓存失效时&#xff08;如&#xff0c;过期时间&#xff09;&#xff0c;同时有大量的请求到达&#xff0c;并且这些请求都需要获取相同的数据&#xff0c;这些请求会同时绕过缓存系统&a…

寻找可能认识的人

给一个命名为&#xff1a;friend.txt的文件 其中每一行中给出两个名字&#xff0c;中间用空格分开。&#xff08;下图为文件内容&#xff09; 题目&#xff1a;《查找出可能认识的人 》 代码如下&#xff1a; RelationMapper&#xff1a; package com.fesco.friend;import or…

C 练习实例77-指向指针的指针-二维数组

关于数组的一些操作 #include<stdio.h> #include<stdio.h> void fun(int b[],int length) {for(int i0;i<length;i){printf("%d ",b[i]);}printf("\n");for(int i0;i<length;i){ //数组作为形参传递&#xff0c;传递的是指针&#xff0…

做跨境用哪种代理IP比较好?

代理IP对于做跨境的小伙伴来说&#xff0c;都是必不可少的工具&#xff0c;目前出海的玩法已经是多种多样&#xff0c;开店、账号注册、短视频运营、直播带货、网站SEO等等都是跨境人需要涉及到的业务。而国外代理IP的获取渠道非常多&#xff0c;那么做跨境到底应该用哪种代理I…

onnx 格式模型可视化工具

onnx 格式模型可视化工具 0. 引言1. 可视化工具2. 安装 Netron: Viewer for ONNX models 0. 引言 ONNX 是一种开放格式&#xff0c;用于表示机器学习模型。ONNX 定义了一组通用运算符&#xff08;机器学习和深度学习模型的构建基块&#xff09;和通用文件格式&#xff0c;使 A…

R语言绘图 | 带标签的火火火火火火火山图 | 标记感兴趣基因 | 代码注释 + 结果解读

在火山图中&#xff0c;我们有时候会想要标注出自己感兴趣的基因&#xff0c;这个时候该怎么嘞&#xff01; 还有还有&#xff0c;在添加标签时&#xff0c;可能会遇到元素过多或位置密集导致标签显示不全&#xff0c;或者虽然显示全了但显得密集杂乱&#xff0c;不易阅读的情况…

6.计算机网络

重要章节、考题比重大&#xff01; 主要议题&#xff1a; 1.网络分类 偶尔考 局域网&#xff1a;覆盖面较小&#xff0c;吞吐效率高&#xff0c;传输速度快&#xff0c;可靠性高&#xff1b; 广域网&#xff1a;传输距离较远&#xff0c;通过分组交换技术来实现&#xff1b…

【图论】树链剖分

本篇博客参考&#xff1a; 【洛谷日报#17】树链剖分详解Oi Wiki 树链剖分 文章目录 基本概念代码实现常见应用路径维护&#xff1a;求树上两点路径权值和路径维护&#xff1a;改变两点最短路径上的所有点的权值求最近公共祖先 基本概念 首先&#xff0c;树链剖分是什么呢&…

简单使用NSIS打包软件

NSIS是一个开源的打包工具. 官网: Download - NSIS (sourceforge.io) 使用这个编译 ​ 但是不建议使用这玩意写脚本,字体太难看了.我用vscode写的脚本,用这个编译的. ​ 写好脚本用这个软件打开, 然后选择这个编译,如果语法有错误 会编译不过,会提醒你哪一行不行,如果编译…

java的23种设计模式03-创建型模式02-抽象工厂方法

一、抽象工厂方法 1-1、抽象工厂方法的定义 抽象工厂模式是一个比较复杂的创建型模式。 抽象工厂模式和工厂方法不太一样&#xff0c;它要解决的问题比较复杂&#xff0c;不但工厂是抽象的&#xff0c;产品是抽象的&#xff0c;而且&#xff1a;有多个产品需要创建&#xff…

python中isinstance函数判断各种类型的小细节

1. 基本语法 isinstance(object, classinfo) Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof. Also return true if classinfo is a type object (new-style class) and object is…

媒体播放器及媒体服务器软件Plex

什么是 Plex &#xff1f; Plex 是一套媒体播放器及媒体服务器软件&#xff0c;让用户整理在设备上的有声书、音乐、播客、图片和视频文件&#xff0c;并通过流式传输至移动设备、智能电视和电子媒体播放器上。Plex 可用于 Windows、Android、Linux、OS X和 FreeBSD。 在接触 N…

什么是IoT物联网平台?

在数字化浪潮的席卷下&#xff0c;物联网&#xff08;IoT&#xff09;技术逐渐渗透到我们生活的方方面面&#xff0c;从智能家居到智慧城市&#xff0c;从工业自动化到智能农业&#xff0c;IoT正以其独特的魅力改变着世界。然而&#xff0c;当我们谈论IoT时&#xff0c;我们究竟…