news 2026/4/3 2:51:53

Java的类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java的类

一.什么是类

在Java中,类(class)是对象的蓝图或模版,它定义了一类对象共有的属性(数据)和行为(方法)。类是面向对象编程(oop)的核心概念,Java程序本质是由一系列类构成的。

二.类的构成

类包含三大核心成员:

1.成员变量:描述对象的状态或属性

2.成员方法:定义对象的行为或功能

3.构造器(构造方法):初始化新创建的对象

三.内部类

内部类是定义在另一个类内部的类。它就像类的“成员”一样,可以访问外部类的所有成员(包括私有的),是实现高内聚的强大工具。

而外部类要想调用内部类的方法或属性,必须先创建内部类的对象。

使用内部类的优势:

  • 更好的封装:将仅服务于外部类的逻辑隐藏起来,外部不可见
  • 直接访问:内部类持有外部类的引用,可以访问外部类的所有成员
  • 代码组织:相关类放在一起,提高可读性
  • 回调机制:内部类是实现事件监听、线程执行的利器

1.内部类的分类

1.成员内部类

不加static,与实例变量,实例方法同级别

  • 成员内部类被protected修饰时,同包或者其他包的类的子类可以访问这个内部类
  • 成员内部类被public修饰时,访问权限完全公开
  • 在JDK(Java Development Kit,Java开发工具)16及以后,成员内部类中可以写静态变量

下面看一些代码

如:

1.在其他外部类中获取内部类的方式
方式1:

外部类名.内部类名 对象名 = new 外部类名().new 内部类名()

在同一包中:

Outer.java

public class Outer { // 内部类Inner是默认没有被任何修饰符修饰的,在本包每个java文件中可以被任意访问 class Inner{ } }

Test.java

public class Test { public static void main(String[] args){ // 获取成员内部类的方式 Outer.Inner oi = new Outer().new Inner(); // 数据类型 变量名 用Outer()对象去调用Inner()内部类 } }
方式2

如果内部类被private关键字修饰(使得外界无法访问,只能在外部类的内部访问),如

public class Outer { private class Inner{ } }

那么在Test.java即其他外部类中就不能按照方式1来创建内部类的对象

这时候,就需要在外部类Outer中编写方法,对外提供Inner内部类的对象

public class Outer { private class Inner{ } public Inner getInner(){ return new Inner(); } }
public class Test { public static void main(String[] args){ // 获取成员内部类的方式 // Outer.Inner oi = new Outer().new Inner(); // 数据类型 变量名 用Outer()对象去调用Inner()内部类 Outer o = new Outer(); Outer.Inner inner = o.getInner(); } }

这时Test.java中还是报错,因为Inner类被private修饰,不能被外界访问了

改成:

利用了多态

public class Test { public static void main(String[] args){ // 获取成员内部类的方式 // Outer.Inner oi = new Outer().new Inner(); // 数据类型 变量名 用Outer()对象去调用Inner()内部类 Outer o = new Outer(); //Outer.Inner inner = o.getInner(); Object inner = o.getInner(); System.out.println(inner); } }

运行Test.java会输出:内部类.Outer$Inner@3f99bd52

其中,内部类是我写的包名(用的中文)、Outer是外部类,Inner是内部类,外部类和内部类用美元$符号进行了分隔以示区分、@后面的3f99bd52是Test.java中内部类Inner对象o的内存地址。

2.外部类的成员变量和内部类的成员变量重名

这个时候怎么去获取不同位置变量的值呢

Outer.java

package 内部类; public class Outer { int a = 10; private class Inner{ private int a = 20; public void show(){ int a = 30; System.out.println(a); } } public Inner getInner(){ return new Inner(); } }

Test.java

package 内部类; public class Test { public static void main(String[] args){ Outer o = new Outer(); Object inner = o.getInner(); Inner actualInner = (Inner) inner; // 强转类型 actualInner.show(); } }

报错分析:

o.getInner()返回的是内部类Inner的实例,不过被赋值给了Object类型的对象。

Object类型对象只能访问其自身定义的方法,无法使用内部类特有的show方法

即使强转也无济于事(因为Inner类被private修饰,其他外部类不能直接访问)

解决:

最直接的方法是将private改为public,而因为Outer.java和Test.java在同一个包中,改成默认形式也可以

package 内部类; public class Outer { int a = 10; class Inner{ private int a = 20; public void show(){ int a = 30; System.out.println(a); } } }
package 内部类; public class Test { public static void main(String[] args){ // 创建内部类的对象 Outer.Inner io = new Outer().new Inner(); io.show(); } }

输出:30

这是因为”就近原则“,在Outer.java中,离sout(a)最近的变量a的值为30

如果要输出Inner类中的成员变量a的值(即值为20的a),需要加上this关键字(this表示方法调用者即Inner对象oi的地址值)

package 内部类; public class Outer { int a = 10; class Inner{ private int a = 20; public void show(){ int a = 30; System.out.println(this.a); } } }

如果要输出Outer类的成员变量a的值(即值为10的a),不能用supper,因为supper表示是父类的引用,应该用外部类的类名去调用,即Outer,并加上.this

package 内部类; public class Outer { int a = 10; class Inner{ private int a = 20; public void show(){ int a = 30; System.out.println(Outer.this.a); } } }

2.静态内部类

被static修饰的内部类称为静态内部类

静态内部类只能访问外部类中的静态方法和静态变量(因为静态的东西是在全局共享的),要访问非静态的方法和变量,要先创建静态内部类的对象。

创建方式:外部类名.内部类名 对象名 = new 外部类名.内部类名();

package 内部类; public class Outer { static class Inner{ public void show1(){ System.out.println("静态类中的非静态方法被调用了"); } public static void show2(){ System.out.println("静态类中的静态方法被调用了"); } } }
package 内部类; public class Test { public static void main(String[] args){ // 由于Inner被static修饰,不能在其他外部类中创建Inner的对象 // 由于被static修饰后是全局共享的,要调用Inner的成员变量或成员方法,直接外部类类名.静态内部类类名.成员变量名/成员方法名() // 又由于show1方法是非静态方法,虽然通过对象名来调用或所属类名即Inner类名来调用 // 但是Inner是静态类,静态类不能调用非静态成员(无论是成员方法还是成员变量) // 所以Outer.Inner.show1(); 自然会报错 Outer.Inner.show2(); } }

输出:静态类中的静态方法被调用了

package 内部类; public class Test { public static void main(String[] args){ // 创建内部类的对象 //Outer.Inner io = new Outer().new Inner(); // 这样是通过创建外部类实例来创建内部类实例,但是被static修饰后内部类不能再依赖与外部类的实例来创建内部类实例了 // 正确的创建内部类实例 Outer.Inner io = new Outer.Inner(); // 静态内部类是全局共享的,只能通过外部类类名来调用或创建实例 io.show1(); } }

输出:静态类中的非静态方法被调用了

同理,静态成员变量也一样。只要记住:静态类只能访问静态的东西(或静态内部类只能被类名.来访问)。静态内部类中要访问非静态的东西必须要创建对象

package 内部类; public class Test { public static void main(String[] args){ // 创建内部类的对象 //Outer.Inner io = new Outer().new Inner(); // 这样是通过创建外部类实例来创建内部类实例,但是被static修饰后内部类不能再依赖与外部类的实例来创建内部类实例了 // 正确的创建内部类实例 Outer.Inner io = new Outer.Inner(); // 静态内部类是全局共享的,只能通过外部类类名来调用或创建实例 io.show1(); io.show2(); // 由于静态方法是全局共享的,所以可以被调用 } }

输出:

静态类中的非静态方法被调用了
静态类中的静态方法被调用了

3.局部内部类

被定义在方法里面的内部类称为局部内部类,类似于方法里面的局部变量

所以public,protected,private,static都不能修饰局部内部类,就像它们也不能用来修饰局部变量,它们只能用来修饰成员

package 内部类; public class Outer { int b = 100; public void method(){ int a = 10; class Local{ String name; void show(){ System.out.println(a); System.out.println(b); System.out.println("局部内部类的非静态方法被调用了"); } static void show2(){ // System.out.println(this.a); // 报错:java: 无法从静态上下文中引用非静态 变量 this。而且静态方法中是没有this关键字的 // 解决方法有两种:一是去掉static,二是将a当成参数传进show2方法中 System.out.println("局部内部内的静态方法被调用了"); } } Local l = new Local(); // 创建局部内部类对象,才能调用局部内部类中的方法 l.show(); l.show2(); Local.show2(); // 这种调用方式IDEA会有show2方法的提示,上一行的调用方式则没有提示 } }
package 内部类; public class Test { public static void main(String[] args){ Outer o = new Outer(); o.method(); } }

输出:

10
100
局部内部类的非静态方法被调用了
局部内部内的静态方法被调用了
局部内部内的静态方法被调用了

4.匿名内部类

匿名内部类本质上就是隐藏了名字的内部类

格式:

new 类名/接口名(){ 重写方法; };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/1 2:09:25

MATLAB基于Shapley组合模型物流需求预测

核心思想与背景 农产品冷链物流需求预测具有典型的季节性、波动性、多影响因素性等特点。单一的预测模型往往只能捕捉数据的部分模式,存在局限性: Shapley组合模型 借鉴了博弈论中夏普利值(Shapley Value)的思想,将多…

作者头像 李华
网站建设 2026/3/28 17:39:01

YOLO26涨点改进 | 全网首发、主干改进篇 | AAAI 2026 | StripNet 主干让 YOLO26 更加强大!利用 StripNet的条形卷积,提升遥感目标检测有效涨点、高效发论文

一、本文介绍 🔥本文将 StripNet 主干网络应用于 YOLO26 版本的目标检测,显著提升了其在高纵横比物体和复杂场景中的检测能力。StripNet 通过条形卷积有效捕捉长条物体的特征,优化了定位精度,并减少了计算冗余,使得模型更加高效简洁。此外,StripNet 提升了YOLO26在遥感…

作者头像 李华
网站建设 2026/3/13 5:18:13

python道理小说阅读器 书架小程序

目录 Python小说阅读器与书架小程序摘要注意事项 开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式! Python小说阅读器与书架小程序摘要 Python开发的小说阅读器和书架小程序通常结合文件操作…

作者头像 李华
网站建设 2026/3/14 20:21:00

Spring Boot + Docker:实现可挂载可热更新的 config.json

文章目录 一、背景:为什么 jar 内的 config.json 不能被覆盖?二、Spring Boot 静态资源加载机制三、解决方案结构四、核心实现:优先读外部文件五、完整 Dockerfile 示例八、总结 前言:在实际项目中,我们经常需要让前端…

作者头像 李华
网站建设 2026/3/28 6:02:24

全面应用掌握!提示工程架构师带你全面掌握Agentic AI国际化应用技能

Agentic AI国际化应用全攻略:从提示工程到落地实践 一、引言:全球化时代,Agentic AI为何成为企业的“破局密钥”? 1.1 一个真实的痛点:跨境企业的“语言墙”与“文化沟” 某跨境电商平台的客服团队曾遇到这样的困境: 来自12个国家的用户用8种语言咨询,客服需要切换翻…

作者头像 李华
网站建设 2026/3/15 16:27:19

CSS Fonts (字体)

CSS Fonts (字体) 在网页设计和开发中,字体是一个至关重要的元素,它不仅能够影响网页的整体视觉风格,还能增强用户的阅读体验。CSS(层叠样式表)提供了强大的工具来控制网页中的字体样式。本文将深入探讨CSS字体相关的各个方面,包括字体的选择、加载、样式以及如何确保跨…

作者头像 李华