news 2026/7/12 18:05:18

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/7/8 20:10:11

samlib.dll文件丢失找不到问题 免费下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…

作者头像 李华
网站建设 2026/6/28 19:21:38

Nginx:如何配置基于ip的虚拟主机(总结二)

一、什么是虚拟主机 虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互…

作者头像 李华
网站建设 2026/7/8 6:29:01

python关于英雄联盟云顶之弈的游戏攻略视频辅助微信小程序

目录英雄联盟云顶之弈游戏攻略视频辅助微信小程序摘要核心功能技术实现代码示例(数据抓取)用户交互设计数据安全扩展方向开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式&#xff…

作者头像 李华
网站建设 2026/7/10 13:21:24

python基于小程序的临沂大学非机电动车车辆充电维修管理系统

目录摘要内容技术实现核心功能创新点应用价值开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!摘要内容 该系统基于Python开发,结合微信小程序平台,旨在为临沂大学校园…

作者头像 李华
网站建设 2026/7/10 0:06:46

模板代码生成原理

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第…

作者头像 李华
网站建设 2026/7/12 11:18:09

C++中的组合模式

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第…

作者头像 李华