Java内部类

内部类的概念
一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员【属性、方法、构造器、代码块、内部类】,内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系


内部类的分类
定义在外部类局部位置上(比如方法内):

  1. 局部内部类(有类名)
  2. 匿名内部类(没有类名,重点)

定义在外部类的成员位置上:

  1. 成员内部类(没用static修饰)
  2. 静态内部类(使用static修饰)


成员内部类
说明:成员内部类是定义在外部类的成员位置,并且没有static修饰。

  1. 可以直接访问外部类的所有成员,包含私有的
class Outer01{   //外部类
private int n1 = 10;
public String name =“张三";
		class lnntero1{
		public void sayoi
		System.out.println("Outer01的n1= " +n1 + " outer01的name = " + name );
	}
}
  1. 可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
  2. 作用域和外部类的其他成员一样,为整个类体(在外部类的成员方法中创建成员内部类对象,再调用方法)
  3. 成员内部类—访问---->外部类(比如:属性)
    访问方式:直接访问
  4. 外部类—访问------>内部类
    访问方式:创建对象,再访问
  5. 外部其他类—访问---->成员内部类
//其它外部类访问内部类
//方式1
Outer01 outer01 = new Outer01();
lnnter01 innter01 = outer01.new Innter01();
//方式2:
InnterO1 innter012 = new Outer01().new lhnter010;
//方式3:使用一个方法来获取,更加简洁(在外部类编写getlnnter01Instance()方法)
Innter01 innter01Instance = new OuterO1().getlnnter01Instance();
  1. 如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

静态内部类
说明:静态内部类是定义在外部类的成员位置,并且有static修饰

  1. 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员 

  2. 可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员

  3. 作用域:同其他的成员,为整个类体

  4. 静态内部类—访问---->外部类(比如:静态属性)
    访问方式:直接访问所有静态成员

  5. 外部类—访问------>静态内部类
    访问方式:创建对象,再访问

  6. 外部其他类—访问---->静态内部类

//外部其他类使用静态内部类
//方式1
//因为静态内部类,是可以通过类名直接访问(前提是满足访问权限)
Outer10.Inner10 inner10 = new Outer10.Inner10();
inner10.say();
//方式2
//编写一个方法,可以返回静态内部类的对象实例.
outer10.Inner10 inner101 = outer10.getInner10();
  1. 如果外部类和静态内部类的成员重名时,静态内部类访问的时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问

局部内部类
说明:局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。

  1. 可以直接访问外部类的所有成员,包含私有的 

  2. 不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final

  3. 作用域:仅仅在定义它的方法或代码块中。

  4. 局部内部类—访问---->外部类的成员
    [访问方式:直接访问]

  5. 外部类—访问---->局部内部类的成员
    访问方式:创建对象,再访问(注意:必须在作用域内)

记住:
(1)局部内部类定义在方法中/代码块
(2)作用域在方法体或者代码块中
(3)本质仍然是一个类

  1. 外部其他类—不能访问----->局部内部类(因为局部内部类地位是一个局部变量)
  2. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
    private int n1 = 10;
    private void m2() { //私有方法
        System.out.println("A的私有方法");
    }
    public void m1() {//方法
        //1.局部内部类是定义在外部类的局部位置,通常在方法
        //3.不能添加访问修饰符,但是可以使用final修饰
        //4.作用域︰仅仅在定义它的方法或代码块中
        final class Inner02 {//局部内部类(本质仍然是一个类)
            //2.可以直接访问外部类的所有成员,包含私有的
            public void f1() {
                //5.局部内部类可以直接访问外部类的成员,比如下面外部类n1 和 m2()
                System.out.println("n1=" + n1);
                m2();
            }
        }
        //6.外部类在方法中,可以创建Inner02对象,然后调用方法即可
        Inner02 inner02 = new Inner02();
        inner02.f1();
    }
}

匿名内部类
(1)本质是类
(2)内部类
(3)该类没有名字
(4)同时还是一个对象

说明:匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名

  1. 匿名内部类的基本语法
new 类或接口(参数列表){
	类体
};


基于接口的匿名内部类
接口式的匿名内部类:创建的匿名类部类对象实现了 new 后面的接口

public class test3 {
    public static void main(String[] args) {
        I1 i1 = new I1() { //创建的匿名类部类实现了I1接口
            @Override
            public void run() {
                System.out.println("跑....");
            }
        };
        i1.run();
    }
}

interface I1{
    public void run();
}


基于的匿名类部类
继承式的匿名内部类:创建的匿名类部类对象 继承了 new 后面的类

public class test3 {
    public static void main(String[] args) {
        new C1(){ //创建的匿名类部类对象为C1的子类
            @Override
            public void eat() {
                System.out.println("吃香蕉");
            }
        }.eat();  //也可直接调用方法
    }
}

abstract class C1 {
    public void eat() {

    }
}


基于参数的匿名类部类
参数式的匿名内部类:将 实现了接口/继承了类 的匿名类部类作为方法参数传递

public class test3 {
    public static void main(String[] args) {
        A(new Animal(){  //作为参数传递
            @Override
            public void run() {
                System. out.println("小狗跑...");
            }
        });
    }
    public static void A(Animal Dog){
        Dog.run () ;
    }
}

interface Animal {
    void run() ;
}
  1. 匿名内部类的语法比较奇特,请大家注意,因为匿名内部类既是一个类的定义同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,对前面代码分析可以看出这个特点,因此可以调用匿名内部类方法。 

  2. 可以直接访问外部类的所有成员,包含私有的

  3. 不能添加访问修饰符,因为它的地位就是一个局部变量

  4. 作用域:仅仅在定义它的方法或代码块中。

  5. 匿名内部类—访问---->外部类成员
    [访问方式:直接访问]

  6. 外部其他类—不能访问----->匿名内部类(因为匿名内部类地位是一个局部变量)

  7. 如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

匿名内部类例子
t1.A(t1包下的A.java文件)
无参的构造方法是受保护的(只有同类、子类、同包)可以访问

public class A<T> {
    protected A() {
        System.out.println("A的protected A()被调用...");
    }
}

t2.test(t2包下的test.java文件)
如果直接创建 A 对象,是会报错的
在这里插入图片描述
但是写成匿名类部类就没问题
这个匿名类部类对象相当于继承了A对象(是A对象的子类),当我们写成new A(){};,相当于调用了匿名类部类对象的无参构造方法-->无参构造默认前面是有super()-->因此又会去调用A的无参构造(protected类型 子类是可以访问的),因此可以创建成功
在这里插入图片描述
在这里插入图片描述


内部类的分类

在这里插入图片描述

在这里插入图片描述

内部类的概念

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

成员内部类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

外部其他类访问
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
使用内部类,必须先创建外部类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当然也可以一步到位
在这里插入图片描述

重复属性名,先访问内部类属性
在这里插入图片描述
在这里插入图片描述

重复属性名,在内部类访问外部类重复名的属性
外部类名.this.属性名
在这里插入图片描述
在这里插入图片描述
内部类不能创建静态属性
但可以创建静态常量

在这里插入图片描述

静态内部类

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

局部内部类

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
但就这样执行是不会有任何结果的
在这里插入图片描述
想要使用局部内部类,就要在方法里,创建局部内部类对象,然后调用
在这里插入图片描述
在这里插入图片描述
访问局部变量
在这里插入图片描述
一点注意
在这里插入图片描述

匿名内部类

在这里插入图片描述

在这里插入图片描述
基于接口的匿名类部类
在这里插入图片描述

在这里插入图片描述

基于类的匿名类部类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
基于抽象类的匿名构造器
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

匿名内部类使用细节

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

匿名类部类使用场景

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值