【java基础】内部类

1|0什么是内部类?

内部类就是定义在类的内部的类,称之为内部类
Java中内部类分为以下4种:

  1. 成员内部类, 内部类在定义时没有使用static修饰(知晓)
  2. 静态内部类,内部类在定义时使用static修饰【Java中唯一可以使用static修饰类的方法】
    (知晓)
  3. 局部内部类,内部类在定义时定义在方法体内部(了解)
  4. 匿名内部类,它属于局部类类的特殊形态(必须会用)

内部类也是类,所以也会被JVM进行编译生成字节码文件【.class文件】

  1. 成员内部类生成字节码文件: 外部类类名$成员内部类类名.class
  2. 静态内部类生成字节码文件: 外部类类名$静态内部类类名.class
  3. 局部内部类生成字节码文件: 外部类类名$数字局部内部类类名.class
  4. 匿名内部类生成字节码文件: 外部类类名$数字.class
    PS: 数字是从1开始逐渐递增【随着类的增加而增加】成员内部类(知晓)

2|0成员内部类(知晓)

外部类可以使用权限修饰符为 public 和 默认的和abstract,成员内部类可以使用【4种权限修饰
符和abstract修饰】,可以将成员内部类看做就是在类中声明成员变量或成员方法,所以成员内
部类是属于对象的

//外部类 public class Outter { //外部类中提供成员变量和方法、静态变量和方法 String name = "小白"; double PI = 3.14; static int age = 10; public static void showInfos(){ System.out.println("外部类静态方法"); } public void display(){ System.out.println("外部类的成员方法"); //需要提供内部类对象创建,才可以使用成员内部类中所提供成员变量和成员方法 InnerClass innerClass = new InnerClass(); innerClass.name ="z"; innerClass.show(); } //提供成员内部类 ---》 成员内部类就是定义在类中类,可以使用任何修饰符除static外 public class InnerClass{ //成员内部类 //可以在成员内部类中提供类的基础定义,但是不可以提供static修饰的属性和方法 //static double PI = 3.14; String name = "小黑"; public void show(){ System.out.println("成员内部类中成员方法"); //如果说在成员内部类中调用与外部类同名属性 //this代表的是InnerClass对象,所以使用this.name System.out.println(this.name); //这种方式访问外部类的成员变量 System.out.println(Outter.this.name); //调用外部类的成员方法【如果没有重名的效果,就不需要使用,外部类类名.this.方式调用】 display(); System.out.println(PI); //成员内部类中是可以调用外部类静态属性和方法 System.out.println(age); showInfos(); } } } class Test{ public static void main(String[] args) { //如何在外部创建成员内部类的对象 //成员内部类是属于外部类所有的,所以提供方式就是 // 外部类类名.内部类类名 内部类对象名 = new 外部类().new 成员内部类(); Outter.InnerClass innerClass = new Outter().new InnerClass(); innerClass.show(); } }

总结: 成员内部类是定义在类中,不使用static修饰,可以使用4种权限修饰符,可以使用
abstract和final修饰,允许继承类与实现接口,成员内部类中不可以定义static修饰变量与方
法,成员内部类是可以直接访问外部类定义属性和方法,如果成员内部类出现了与外部类属性重
名,可以使用【this 和 外部类.this】进行区分,外部类要访问成员内部类的属性和行为时,提供
成员内类的对象
---》 外部类类名.内部类类名 内部类对象名 = new 外部类().new 内部类();

3|0静态内部类(知晓)

静态内部类和成员内部类几乎与是一样的,唯一不点在于静态内部类使用static进行了修饰
PS:这是Java中类唯一可以使用static修饰的形式

//外部类 public class Outter { //外部类中提供成员变量和方法、静态变量和方法 String name = "小白"; double PI = 3.14; static int age = 10; public static void showInfos(){ System.out.println("外部类静态方法"); } public void display(){ System.out.println("外部类的成员方法"); //调用静态内部类中静态属性和方法 ---》 静态内部类类名.静态属性和静态方法即可 System.out.println(InnerClass.name); //调用静态内部类中成员属性和方法 ---》 需要提供静态内部类的对象 new Outter.InnerClass().show(); } //提供静态成员内部类 ---》 静态内部类就是定义在类中类,可以使用static修饰符修饰 public static class InnerClass{ //静态内部类 // 静态内部类可以提供普通类中所有可以提供操作【成员变量和方法、静态变脸和方法】 double PI = 3.15; static String name = "小黑"; public void show(){ //在静态内部类中是不用担心 属性重名问题 //不是可以使用 外部类类名.this方法访问外部的属性【static中是不允许使用this和super关键字】 //只能在静态内部类中创建外部类对象,才可以访问外部类成员变量和成员方法 System.out.println(new Outter().name); //调用外部类静态方法和静态属性 --> 外部类类名.静态属性或静态方法即可 System.out.println(Outter.age); Outter.showInfos(); //静态内部类中的属性和方法直接调用即可 System.out.println(PI); System.out.println(name); } } } class Test{ public static void main(String[] args) { //提供静态内部类对象创建 //外部类类名.静态内部类类名 对象名 = new 外部类类名.静态内部类类名(); Outter.InnerClass innerClass = new Outter.InnerClass(); innerClass.show(); } }

总结: 静态内部就是使用static修饰类【Java中只有这个类可以使用static修饰】,可以使用所
有权限修饰符,abstract和final修饰,静态内部类和静态属性和静态方法是一样都属于类,静态
内部类中是可以定义【成员变量和方法、静态变量和方法】,静态内部类中不允许明确访问方式
获取外部类this对象即【外部类类名.this】,所以在静态内部类中访问外部类成员变量和成员方
法,需要提供外部对象才可以,外部类静态变量和静态方法直接访问即可,如果有重名【外部类
类名.静态变量/静态方法】
静态内部类如果要创建对象
外部类类名.静态内部类类名 对象名 = new 外部类类名.静态内部类类名();

4|0局部内部类(了解)

这个内部类不允许使用任何修饰符,只能定义在方法内部与局部变量是平级关系,访问作用域仅
限在方法的内部

//外部类 public class Outter { //提供一个成员方法 public void show() { //局部变量 final int age = 18; //提供局部内部类【局部变量是平级关系】 class InnerClass { //局部内部类中是不允许定义static修饰属性和方法 //允许提供成员变量和成员方法 String gender = "男"; public void display() { //在局部内部类中访问方法中局部变量 /* IDEA提供错误提示信息 Variable 'age' is accessed from within inner class, needs to be final or effectively final 如果局部内部类使用方法提供的局部变量,这个局部变量必须是final修饰 */ System.out.println(age); } } //局部内部类只能在方法体的内部创建对象和使用,外界是无法访问到这个类中 new InnerClass().display(); //在此在方法体的内部修改成员变量 // age = 20; } }

为什么,局部内部类访问局部变量之后需要使用final声明?
final修饰局部变量的存储空间会发生改变,存储不再是栈中,而是方法区中常用池,局部变量就会
变成“引用”常量
局部内部类是声明在方法体内部,就会存在一个问题,局部内部类是随着方法而开始创建空间,
随着方法消亡开始回收空间,如果在方法内声明局部变量存储空间是栈【随着方法开始而创建随
着方法消亡会销毁】,如果局部内部类使用了这个局部变量,那么堆中地址就会和栈中位置产生
一个联系,堆中局部内部类就会引用到栈中局部变量,如果发生方法执行完毕,栈中空间空间会
进行立即回收,但是堆中局部内部类是不会被立即回收【GC机制】,就会出现堆栈存在一个“指
向空”引用,内报错了,所以使用final修饰符将局部变量修改为局部常量,将存储从栈中移动到方
法区中常量池,这样一来就算栈中空间被回收,但是方法区种空间还在,所以可以等待堆中局部
内部正常回收之后断练习,保证不会出现引用错误。

5|0匿名内部类

/抽烟接口 public interface ISmoking { /** * 抽烟方法 * @param name 抽烟的名字 */ void smoke(String name); } //按照以往的方法实现接口 public class Outter implements ISmoking { @Override public void smoke(String name) { System.out.println("正在抽的烟是:"+name); } } public class Test { public static void main(String[] args) { //调用抽烟方法展示抽象操作 //1.提供实现ISmoking接口对象 Outter outter = new Outter(); //2.通过outter对象调用smoke方法就可以执行抽烟操作 outter.smoke("华子"); //这个方法可以接收的对象必须是实现ISmoking接口的对象【利用就是面向兑现中多态】 showInfosSmokeName(outter); //但是,如果当前实现接口类只使用一次,不在重复使用了,这样创建方式就比较繁琐也不利于管理 //所以Java就提供了一个更加便捷处理方式,提供匿名内部类作为接口的实现操作 /* 第一种 主要是针对与方法参数为接口类型进行赋值操作 --》完全匿名内部类 new 接口名(){ 提供接口中抽象方法的实现; } *//* 第二种方式,针对匿名内部类所创建对象进行存储操作 接口名 对象名 = new 接口名(){ 接口抽象方法的实现 } */ //smoking 存储的就是匿名内部类的引用【使用 new ISmoking的形式将后面的匿名内部类进行对象向上转型】 new ISmoking(){ @Override public void smoke(String name) { System.out.println("完全匿名内部类实现接口:"+name); } }.smoke("芙蓉王"); //这种形式主要是针对方法参数赋值使用的 //第二种 主要是针对于接口对象的赋值操作 --》局部匿名内部类 ISmoking smoking = new ISmoking() { @Override public void smoke(String name) { System.out.println("使用匿名内部类创建了接口对象:"+name); } }; smoking.smoke("煊赫门"); //可以使用匿名内部类的这种语法便捷的对方法中参数进行赋值操作 showInfosSmokeName(new ISmoking() { @Override public void smoke(String name) { System.out.println("匿名内部类对接口参数赋值:"+name); } });// 使用匿名内部类形式对接口参数进行赋值操作 } //提供一个方法这个方法的参数类型是接口类型 public static void showInfosSmokeName(ISmoking smoking){ smoking.smoke("小熊猫"); } }

__EOF__

本文作者blanset
本文链接https://www.cnblogs.com/blanset/p/16907344.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   求道之愚者  阅读(156)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示