Java成员类(内部类、匿名内部类)

Java 中内部类指的是声明在一个类内部的类,它可以访问外部类的私有变量和方法,而外部类不能直接访问内部类的成员。内部类的主要作用是为外部类提供一种封装和组织代码的方式。

内部类可以解决Java类单继承的问题,因为内部类和外部类可以相互访问。


类型: 内部类分为四种类型:

  • 成员内部类(Member Inner Class): 定义在外部类内部的非静态类。它可以访问外部类的成员。
  • 静态内部类(Static Inner Class): 定义在外部类内部的静态类。它不依赖于外部类的实例,可以直接通过外部类名访问。
  • 局部内部类(Local Inner Class): 定义在方法内部的类。它只在方法的作用域内可见。
  • 匿名内部类(Anonymous Inner Class): 没有显式类名的内部类,通常用于创建实现接口或继承类的匿名对象。

访问修饰符public仅适用于顶级类和成员类 ,不适用于本地类或匿名类。访问修饰符 protected和 private 仅适用于成员类

static 修饰的类仅适用于成员类和本地类

访问方式: 访问内部类的方式取决于内部类的型。类成员内部类通过外部类的实例访问,而静态内部类通过外部类名访问。成员类属于类的成员,所以可以调用外部类的 private 成员。外部类可以访问成员类的 private 成员


在外部类中创建成员内部类的实例:

java 复制代码
public class OuterClass {
    private int x = 10;
    // 成员类
    public class InnerClass {
        public void print() {
            System.out.println("x is " + x);
        }
    }
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.print(); // 输出:x is 10
    }
}

局部内部类的定义方式如下:

java 复制代码
class Outer {
   void print() {
      final int b = 5;
      // 局部内部类
      class Inner {
         void print() {
            System.out.println("b = " + b);
         }
      }
      Inner inner = new Inner();
      inner.print();
   }
}

匿名内部类的 定义方式如下:

匿名类不能使用修饰符,在方法的内部,对外隐藏。不能是 static ,隐式 final 类。匿
名类没有类名,没有构造方法。

java 复制代码
interface A {
   void print();
}
class Outer {
   void print() {
      // 匿名内部类
      A a = new A() {
         public void print() {
            System.out.println("匿名内部类输出");
         }
      };
      a.print();
   }
}

静态内部类的定义方式如下:

java 复制代码
class Outer {
   private static int c;
    // 静态内部类
   static class Inner {
      void print() {
         System.out.println("c = " + c);
      }
   }
}

内部类的代码演示:

java 复制代码
package com.member;

/**
 * 成员类【内部类】
 */
public class Demo {
   static int a;
   static int B = 2;
   static {
       System.out.println("demo static{}");
   }
   static class DemoInner{
       int c = 0;
       static int a;
       static int B = 4;
       static {
           System.out.println("Inner static{}");
       }
       public static void t(){
           System.out.println(123);
       }
       public void test(){
           System.out.println(Demo.B);  // 调用外部类的静态变量
           System.out.println(B);       // 调用当前内部类的静态变量
           System.out.println(this.B);  // 调用当前内部类的静态变量

           new Demo().new Demo3().test();   // 调用另一个非静态内部类的非静态方法

           Demo.test();     // 调用外部类的静态方法
       }
   }
   class Demo3{
       static int B = 6;
       static int a;
       int c =12;
       static {
           System.out.println("demo3 static{}");
       }

       public void test(){
           System.out.println(this.B);      // 调用当前非静态类的静态变量
           System.out.println(Demo.B);      //  调用外部类的静态变量
           // 在实例成员类中可以使用 外部类.this 表示外部类对象 (实例成员类是由外部类对象创建的)成员类中的 this 表示的是成员类
           System.out.println(Demo.this.B);     // 调用外部类的静态变量
       }
   }
   public static void test(){
       System.out.println(DemoInner.a);
       System.out.println(Demo3.a);
       new DemoInner().test();      // 调用静态内部类的非静态方法
   }
}
class Test{
    public static void main(String[] args) {
        Demo.DemoInner i = new Demo.DemoInner();
        System.out.println(i.c);    // 调用内部类的实例变量
        Demo.DemoInner.t();    //调用内部类的静态方法
        int a = Demo.DemoInner.a;    // 调用内部类的静态变量


        int c = new Demo().new Demo3().c;    // 调用非静态类的实例变量
        int a1 = Demo.Demo3.a;    // 调用非静态类的静态变量
        Demo.Demo3 demo3 = new Demo().new Demo3();

        Demo.test();    // 调用外部类的静态方法

    }
}

总结:内部类和外部类区别**?**

访问修饰符:
外部类只能有两种访问权限: public 以及 package - access
内部类可以有四种访问权限: public / protected / package - access / private
也就是说:访问修饰符public仅适用于顶级类和成员类,不适用于本地类或匿名类。访问修饰符 protected和 private 仅适用于成员类。
static 修饰: 外部类不可以使用 static 修饰类,内部类可以
使用:外部类可以直接被使用,内部类的使用则依赖于外部类

相关推荐
翔云API4 分钟前
身份证识别接口的应用场景和作用
运维·服务器·开发语言·自动化·ocr
学java的小菜鸟啊17 分钟前
第五章 网络编程 TCP/UDP/Socket
java·开发语言·网络·数据结构·网络协议·tcp/ip·udp
zheeez21 分钟前
微服务注册中⼼2
java·微服务·nacos·架构
立黄昏粥可温21 分钟前
Python 从入门到实战22(类的定义、使用)
开发语言·python
PerfMan24 分钟前
基于eBPF的procstat软件追踪程序垃圾回收(GC)事件
linux·开发语言·gc·ebpf·垃圾回收·procstat
程序员-珍25 分钟前
SpringBoot v2.6.13 整合 swagger
java·spring boot·后端
徐*红32 分钟前
springboot使用minio(8.5.11)
java·spring boot·spring
聆听HJ33 分钟前
java 解析excel
java·开发语言·excel
溪午闻璐36 分钟前
C++ 文件操作
开发语言·c++
AntDreamer37 分钟前
在实际开发中,如何根据项目需求调整 RecyclerView 的缓存策略?
android·java·缓存·面试·性能优化·kotlin