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形成对比
在这里插入图片描述
默默地问一句:你累不累
在这里插入图片描述

相关文章
|
29天前
|
Java
java中,剩下的这两个内部类不太好理解!
java中,剩下的这两个内部类不太好理解!
12 0
|
29天前
|
Java 编译器
java中常见的几种内部类,你会几个?(未完)
java中常见的几种内部类,你会几个?(未完)
14 1
|
4月前
|
Java 数据安全/隐私保护
【零基础学Java】—内部类的概念与分类(三十)
【零基础学Java】—内部类的概念与分类(三十)
|
7天前
|
安全 Java 编译器
接口之美,内部之妙:深入解析Java的接口与内部类
接口之美,内部之妙:深入解析Java的接口与内部类
25 0
接口之美,内部之妙:深入解析Java的接口与内部类
|
9天前
|
Java API
Java基础—笔记—内部类、枚举、泛型篇
本文介绍了Java编程中的内部类、枚举和泛型概念。匿名内部类用于简化类的创建,常作为方法参数,其原理是生成一个隐含的子类。枚举用于表示有限的固定数量的值,常用于系统配置或switch语句中。泛型则用来在编译时增强类型安全性,接收特定数据类型,包括泛型类、泛型接口和泛型方法。
9 0
|
9天前
|
存储 Java
java接口和内部类
java接口和内部类
|
1月前
|
Java 编译器
详解java各种内部类
详解java各种内部类
|
1月前
|
设计模式 Java
JAVA内部类
JAVA内部类
10 1
|
2月前
|
Java
JAVA基础--内部类和静态内部类、单例模式---静态内部类剖析
JAVA--内部类和静态内部类、单例模式---静态内部类剖析
38 9
|
4月前
|
Java
【Java基础】类名、抽象类、接口名的参数传递及成员内部类、局部内部类和匿名内部类的使用
【Java基础】类名、抽象类、接口名的参数传递及成员内部类、局部内部类和匿名内部类的使用
40 0