8.高级-内部类

介绍

一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套其他类的类称为外部类。内部类最大的特点是可以直接访问私有属性,并且可以体现类与类之间的包含关系。
注意:内部类是学习的难点,同时也是重点,后面看底层源码时,有大量的内部类。

1.基本语法

class Outer{//外部类

       class Inner{//内部类

       }
}
class Other{//外部其他类

}

2.内部类的分类

1.定义在外部类局部位置上(比如方法内)

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

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

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

3.局部内部类

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

  1. 可以直接访问外部类的所有成员,包含私有的;
  2. 不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final修饰符,因为局部变量也可以使用final;
  3. 作用域:仅仅在定义它的方法或代码块中;
  4. 局部内部类–访问—》外包类的成员【访问方式:直接访问】;
  5. 外部类–访问—》局部内部类的成员【访问方式:创建对象,在访问(必须在作用域内)】;
  6. 外部其他类—不能访问-----》局部内部类(因为局部内部类地位是一个局部变量);
  7. 如果外部类和局部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

class Outer {
    private int n1 = 100;
    private void m2(){
        System.out.println("m2");
    }//私有方法

    public void m1(){//方法
        String name = "小红";
        //1.局部内部类是定义在外部类的局部位置,通常在方法里
        //3.不能添加访问修饰符,但是可以使用final修饰
        //4.作用域:仅仅在定义它的方法或代码块中
        final class Inner{//局部内部类(本质仍然是一个类)
            //2.可以直接访问外部类的所有成员,包含私有的
            private int n1 = 200;
            public void f1(){
                //5.局部内部类可以直接访问外部类的成员,比如下面的变量和方法
                System.out.println("n1= " + n1);
                //如何访问外部类的n1?
                //语法--->外部类名.this.成员
                //Outer.this.n1 本质就是外部类的对象,那个对象调用了m1方法,Outer.this就是那个对象
                System.out.println("n1= " + Outer.this.n1);
                m2();
            }

        }
        //6.外部类在方法中,可以创建Inner对象,然后调用方法即可
        Inner inner = new Inner();
        inner.f1();
    }


}

注意:

  1. 局部内部类定义在方法或代码块中
  2. 作用域在方法体或者代码块中
  3. 本质还是一个类

4.匿名局部内部类

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

  1. 本质是类;
  2. 还是内部类;
  3. 该类没有名字(系统会自动生成名字);
  4. 同时还是一个对象。
//基本语法
new 类或接口(参数列表){
         类体
};

//class 匿名内部类 extends 类或接口(参数列表){
         //类体
//};

1)需求:想要用动物接口,并创建猫对象。
2)传统方式,是写一个猫类,在实现动物接口,最后创建对象;
3)要求:猫类只能使用一次,后面再不使用;
4)可以使用匿名内部类来实现该需求;
5)动物接口是编译类型,匿名内部类是运行类型;
6)底层会帮我们实现接口的操作,并且会分配一个类名,类名就是[类名$1];
7)jdk底层在创建匿名内部类,立马就创建了[类名$1]实例,并且把地址返回给动物接口;
8)匿名内部类使用一次,就不能使用了。

1.匿名内部类的使用

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

new A(){
   
   public void cry(){
       System.out.println("hello~~");
   }

}.cary();
A a = new A(){
   
   public void cry(){
       System.out.println("hello~~");
   }

};
a.cry();//动态绑定,运行类型是匿名内部类
  1. 可以直接访问外部类的所有成员,包括私有的;
  2. 不能添加访问修饰符,因为它的地位就是一个局部变量;
  3. 作用域:仅仅在定义它的方法或代码块中;
  4. 匿名内部类–访问—>外部类成员【访问方法:直接访问】;
  5. 外部其他类–不能访问—>匿名内部类(因为匿名内部类地位是一个局部变量);
  6. 如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类成员,则可以使用(外部类名.this.成员)去访问。

2.匿名内部类的使用场景

  1. 把匿名内部类当做实参直接传递。
    只使用一次的话,写匿名内部类会简洁很多
public class Test2 {
    public static void main(String[] args) {

        //使用匿名内部类,当做实参直接传递,简洁高效
        f1(new ISS(){
            @Override
            public void show() {
                System.out.println("调用到我了");
            }
        });

        //传统写法
        f1(new XXX());

    }
    //静态方法,形参是接口类型
    public static void f1(ISS iss){

        iss.show();

    }
}

//接口
interface ISS{
    void show();
}

//传统写法--->编程领域 硬编码
class XXX implements ISS{


    @Override
    public void show() {
        System.out.println("也调用到我了,我是传统写法");
    }
}

5.成员内部类

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

  1. 可以直接访问外部类的所有成员,包含私有的;
  2. 可以添加任意访问修饰符,因为它的地位就是一个成员;
  3. 作用域和外部类的其他成员一样;
  4. 成员内部类—访问----》外部类成员【访问方式:直接访问】;
  5. 外部类—访问—》成员内部类【创建对象,再访问】;
  6. 外部其他类----访问----》成员内部类。
    1)外部类.内部类 类名称 = 外部类名称.new 内部类();
    2)在外部类中写一个方法,返回内部类;
  7. 如果外部类和内部类的成员重名时 ,内部类访问的话,默认遵循就近原则,如果想访问,则可以使用【外部类名.this.成员】去访问
class Outer {//外部类
   private int n1 = 10;
   public String name = "小红";

    class Innter {//这是一个成员内部类
             public void say(){
             
             }
    }
  //写方法
  public void t1(){
          使用了成员内部类
         Innter  aa = new Innter();
         aa.say();
  }
}

6.静态内部类

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

  1. 可以直接访问外部类的所有静态成员,包含私有的,但是不能直接访问非静态成员;
  2. 可以添加任意访问修饰符,因为它的地址就是一个成员;
  3. 作用域:同其他的成员,为了整个类体;
  4. 静态内部类–访问—》外部类(比如,静态属性)【访问方式:直接访问所有静态成员】;
  5. 外部类—访问-----》静态内部类【访问方式,创建对象,再访问】;
  6. 外部其他类—访问----》静态内部类
    1)外部类对象.静态内部类(除了私有的,需要满足访问权限);
    2)写一个方法,返回一个静态内部类对象;
  7. 如果外部类和静态内部类的成员重名时,静态内部类访问时,默认遵循就近原则,如果想访问外部类的成员,则可以使用【外部类名.成员】 去访问。(不用加this,因为这是静态内部类);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值