Java中的四大内部类

简介: Java中的内部类在源码中应用的十分广泛

@TOC

前言

内部类是面向对象中类的比较复杂的一个成员,他最大的特点就是可以实现类与类的包含关系,可以直接访问类中的私有属性,是面向对象编程过程中简化思想的一种体现。
在这里插入图片描述

内部类⭐

一.定义及语法

🟠定义

🟤==一个类的内部完整嵌套了另一个类的结构,被嵌套的类称为内部类,嵌套其他类的类称为外部类==

🟤语法:

class A{// 外部类
  class B{//内部类
  ....
  }
}

🔴内部类的分类:

1.局部内部类
2.匿名内部类
3.成员内部类
4.静态内部类

二.局部内部类

🟢内部类定义在外部类的局部位置,比如在==方法(或者代码块)中==
例如:

class A{
public void m1(){   
class B{  //内部类B定义在A中的m1方法
.....
    }
  }
}

🟢内部类不能添加访问修饰符,它的本质是一个==局部变量==,但可以用final修饰,可以把它理解成
例如:
在这里插入图片描述
🟢作用域仅在定义它的局部位置(方法或者代码块)
🟢局部内部类可以直接访问外部类的成员
例如:

class A {//外部类
    private int n1 = 100;
    private void m2() {  //外部类成员方法
        System.out.println("m2被调用");
    }
    public void m1() {
        System.out.println("m1方法被调用");
        class B {                   //局部内部类
            public void f1() {
      //可以直接访问外部类的所有成员,包含私有的
        System.out.println("n1=" + n1); //局部内部类访问外部类属性
       }
     }
   }
}

🟢外部类访问局部内部类成员时,内部类中要先创建对象再访问

class A {//外部类
    private int n1 = 100;
    private void m2() {
        System.out.println("m2被调用");
    }
    public void m1() {
        System.out.println("m1方法被调用");
              class B {//局部内部类 
            public void f1() {
          System.out.println("f1方法被调用");
            }
        }
        B b = new B();  //创建对象
        B.f1();   
    }
}

🟢==外部其他类不能访问局部内部类(因为他是一个成员变量)==,当外部类和局部内部类成员重名时,内部类的访问遵循==就近原则==,若要访问外部类成员则须通过(外部类名.this.成员)来进行访问
例如:
就近原则的体现

class A{
    private int n1=10;
    public void m1(){
        class B{
         private int n1=20;
         public void show(){
             System.out.println(n1);
         }
       }
        B b = new B();
        b.show();
    }
}

▶️运行结果:
在这里插入图片描述
利用this访问外部类成员

class A{
    private int n1=10;
    public void m1(){
        class B{
         private int n1=20;
         public void show(){
             System.out.println(A.this.n1);  //访问外部类的 n1
         }
       }
        B b = new B();
        b.show();
    }
}

▶️运行结果:
在这里插入图片描述

三.匿名内部类(🚩)

🟢匿名内部类是用来简化开发的,他并没有什么新颖的功能,只是能把复杂的问题简单化,比如在一个功能中,一个类(或者接口)之下我有很多子类要去继承(或者实现),按照常理,我需要一个一个子类地去写出来,并且实例化来调用类下的成员,但是使用匿名内部类,就不需要进行上述的重复操作,我只需要通过匿名内部类针对父类(或者接口)创建相应对象,在类内部重写方法即可.

定义在外部类的局部位置,比如方法(或者代码块)中,它具有一个特征没有类名,

语法:

class A{                       // 外部类
public void m1(){ 
   new 类或者接口(参数列表){// 匿名内部类
         .....
    }
  }
}

🟢匿名内部类是一个类的定义,同时它本身也是一个对象,他同时具有类和对象的特征,因此可以用匿名内部类来调用方法
例如

class A{             // 外部类
public void m1(){ 
   new B(){       // 匿名内部类
     public void m2(){
        ......
       }
    }.m2()
  }
}

🟢可以直接访问外部类的所有成员,包含私有成员
例如:

class A{
    private int n1=10;
    public void m1(){
        new B(){
            @Override
            void play() {
                System.out.println(n1);//访问外部属性
            }
        };
    }
}
class B{
    void play(){};
}

🟢匿名内部类可以直接访问外部类成员,包含私有

class A{
    private int n1=10;
    public void m1(){
        new B(){
            @Override
            void play() {
                System.out.println(n1);
            }
        };
    }
}
class B{
    void play(){};
}

🟢外部其他类不能访问匿名内部类,因为它是一个局部变量,作用域在定义它的方法或者代码块中
🟢外部类和内部类成员重名时,遵循就近原则访问,访问外部类成员通过(外部类名.this.成员)来访问
例如:

class A{
    private int n1=10;
    public void m1(){
        new B(){
            public int n1=100;
            @Override
            void play() {
                System.out.println(A.this.n1);
            }
        };
    }
}
class B{
    void play(){};
}

==匿名内部类特性最经的典体现--------当作参数传递给对象==

public class EG {
    public static void main(String[] args) {
        new Cellphone().testWork(new PC() {
            @Override
            public double work(double n1, double n2) {
                return n1+n2;
            }
        },10,4);   //这是匿名内部类经典使用场景,作为参数传递给对象
    }
}
interface PC{
 double work(double n1,double n2);
}
class Cellphone {
    public void testWork(PC pc,double n1,double n2){
        double result=pc.work(n1,n2);
        System.out.println("计算后的结果是:"+result);
    }
}

四.成员内部类

🟢成员内部类定义在外部类的成员位置而不是方法(或者代码块)中,他和局部内部类很相似,但是区别在于它可以添加任意修饰符,因为它==本身就是一个成员==
例如:

class A {
    private int n1 = 20;
    public class B {  //成员内部类
        public void m1() {  //可以添加任意修饰符
        .......
        }
    }
 }

🟢由于它是一个成员,所以他的作用域是整个类体,我在外部类成员方法中==直接创建成员内部类的对象调用它的方法就是很好的体现==
例如:

class A {
    private int n1 = 20;
    public class B {  //成员内部类
        public void m1() {  //可以添加任意修饰符
        .......
        }
    }
    public void m2(){ //利用外部类A创建的方法来调用这个成员
    new B().m1();  
     }
 }

🟢成员内部类可以直接访问外部类成员
例如:

class A {
    private int n1 = 20;
    public class B {  //成员内部类
        public void m1() {  //可以添加任意修饰符
       System.out.println(n1);
        }
    }
 }

🟢外部类创建对象再访问成员内部类,第二个例子已经展示
🟢外部类和内部类成员重名时,遵循就近原则访问,访问外部类成员通过(外部类名.this.成员)来访问,和上述类的方法一致

五.静态内部类

🟢静态内部类是定义在外部类的成员位置,并且有static修饰
它的性质和成员内部类基本一致,唯一不同的点在于,他虽然可以直接访问外部类的所有成员,但不能直接访问非静态成员
例如:
非静态成员n1和静态成员n2形成对比
在这里插入图片描述
默默地问一句:你累不累
在这里插入图片描述

相关文章
|
2月前
|
Java 编译器
【Java】内部类
【Java】内部类
22 0
|
4月前
|
Java
【Java基础面试二】、个Java文件里可以有多个类吗(不含内部类)?
这篇文章讨论了Java文件中类的定义规则,指出一个Java文件可以包含多个类(不包含内部类),但其中最多只能有一个public类,且如果有public类,它的名称必须与文件名一致。
|
4月前
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
39 5
|
5月前
|
Java
Java进阶之内部类
【7月更文挑战第13天】Java内部类增进代码组织与封装,允许直接访问外部类成员,包括私有成员。主要有四种类型:成员、静态、局部和匿名内部类。匿名内部类常用于一次性实现接口或扩展类。内部类可隐藏实现细节,减少命名冲突,并在特定上下文中定义辅助类。示例展示了静态和非静态内部类如何在Shape类中封装Circle和Rectangle。使用内部类能提升代码可读性,但可能增加复杂性。
39 6
|
4月前
|
Java
【Java】内部类、枚举、泛型
【Java】内部类、枚举、泛型
|
6月前
|
Java
一篇文章讲明白Java中内部类详解—匿名内部类
一篇文章讲明白Java中内部类详解—匿名内部类
95 2
|
6月前
|
设计模式 Java 编译器
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
|
6月前
|
Java 编译器
24. 【Java教程】内部类
24. 【Java教程】内部类
30 2
|
7月前
|
Java 程序员
Java的内部类与匿名类的技术性文章
Java的内部类与匿名类的技术性文章
44 1
|
7月前
|
Java
Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)
Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)
62 3