内部类和代码块

内部类

类中的五大成员:属性,方法,构造器,代码块,内部类

源码中会有大量内部类

内部类的分类:

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

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

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

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

局部内部类:

  1. 在外部类的局部位置,通常在方法(或代码块)里
  2. 可以访问到外部类的所有成员,包括私有的
  3. 不能添加访问修饰符,但是可以用final修饰
  4. 作用域:仅仅在定义它的方法里
  5. 外部类在方法中又可以创建局部类的对象,任何调用方法
  6. 本质上还是一个类,类有的它也有
  7. 当外部类和内部类属性或者方法重复了,可以通过外部类.this.方法(属性)

匿名内部类:

为什么要有匿名内部类:

当我们有一个父类或者接口,有一个子类要去继承或者实现他们,但这个子类我们只用一次,那么创建这个子类就显得麻烦,所以就有了匿名内部类

public class AnonymousClass {
    public static void main(String[] args) {
       A a=new A() {			//这个匿名内部类的编译类型:A					
            @Override			//运行类型:匿名内部类
            public void a() {//在这个底层其实创建了匿名内部类后,马上就创建了内部类的实例,并将他返回给a
                System.out.println("你好");
            }
        };
       a.a();
    }
}
interface A{
    void a();
}

基础概念:

  1. 本质是一个类,内部类,该类没有名字,同时还是一个对象
  2. 基础语法:new 类或接口(参数列表)
  3. A a=new A() {重写的抽象方法},A为接口,此时编译类型:A,运行类型:匿名内部类
  4. 在这个底层其实创建了匿名内部类后,马上就创建了内部类的实例,并将他返回给a
  5. 并不是没有名字,其实用getClass可以获取到这个类,但是这个实例一用完就会销毁
  6. 匿名内部类无法向下转型(拿不到),所以调用不到不同于父类的特有方法

细节(和局部内部类一样):

  1. 同样是内部类,所以也可以访问到外部类的所有成员
  2. 不能添加修饰符,因为它本身地位就是一个局部变量
  3. 作用域:定义它的方法或代码块里
  4. 外部其他类不能实例化这个类,因为它就实例化一次就销毁了
  5. 当外部类和内部类属性或者方法重复了,调用会有就近原则,可以通过外部类.this.方法(属性)调用内部类里的方法属性

应用场景:

  • 跟多态传实参连用
interface I{
    void a1();
}
class test2{
    public static void main(String[] args) {
       method(new I() {
           @Override
           public void a1() {
               System.out.println("使用匿名类实现多态传参");
           }
       });
    }
    public static void method(I i){
            i.a1();
    }
}

成员内部类:

  1. 可以访问到内部类的所有成员,包括私有的
  2. 可以添加任何权限修饰符,因为它本身就是一个成员
  3. 可以访问到外部类的所有成员,包括私有的
  4. 外部类访问到内部类,创建内部类对象
  5. 外部其他类访问成员内部类,不能直接实例化,而要先调用再实例化
  6. 当外部类和内部类属性或者方法重复了,调用会有就近原则,可以通过外部类.this.方法(属性)调用内部类里的方法属性

外部其他类访问成员内部类:

1641701834764

静态内部类:

  1. 放在外部类的成员位置
  2. 使用static修饰
  3. 可以访问到外部类的所有静态成员,,但不能访问到非静态类的
  4. 可以是任意权限修饰符
  5. 作用域,同其他成员,为整个类
  6. 外部类访问静态内部类,创建对象访问
  7. 外部的其他类访问,通过外部类名.内部类名调用

总结:

  • 内部类分为局部内部类:局部内部类,匿名内部类

    • 局部内部类:

      • 定义在方法和代码块中
      • 能访问到外部类的所有属性和方法
      • 不能添加修饰符
      • 作用域在方法或者代码块
      • 本质还是一个类,类该有的它都有
      • 外部类向访问它,就必须在创建它的对象,在调用
      • 当内部类和外部类属性或者方法有重复名,就近原则
    • 匿名内部类

      • 满足局部内部类

      • 出现的原因,是解决了继承和实现如果只实例化次数很少,而需要去创建子类,很麻烦

      • 基础语法:new 接口(父类){重写的方法};

      • 编译类型是接口或者父类,但是运行类型还是匿名内部类

      • 应用可以跟多态的实参一起用

  • 内部类还有成员内部类:成员内部类,静态成员内部类

    • 成员内部类

      • 是一个成员

      • 可以访问到外部类的所有属性和方法

      • 既然是一个成员,那肯定可以有权限修饰符

      • 作用域:整个类

      • 外部类访问它,必须得创建实例

    • 静态成员内部类:

      • 除了调用外部类属性时,只能调用静态的
      • 外部的其他类调用这个类,用外部类.这个类的形式,把这个类当成类成员就行

代码块:

介绍:

代码块又叫初始化块,属于类的成员,类似于方法,将逻辑语句封装到方法体里,不能通过对象等显性调用,而是在加载类时,或创建对象时隐形创建

基础语法:【修饰符】{

代码

}

修饰符只能是static

有什么用:

对构造器的补充,当我们的类里几个构造器都有相同的代码,显得冗余,这个时候就可以使用代码块,代码块,会在创建对象时,先于构造器里的内容创建

public class Code1 {
    public static void main(String[] args) {
        A a = new A(20);
        A a1 = new A(20,"lc");
    }

}
class A{
    {
        System.out.println("开始了");
    }
    A(int a){
        System.out.println("我的"+a+"岁");
    }
    A(int a,String name){
        System.out.println(name+"的"+a+"岁");
    }
}

细节:

  1. 被Static修饰的代码块,叫静态代码块,它随着类的加载而产生,并且只执行一次普通代码块每创建一个对象执行一次
  2. 类在什么时候会被加载(重要)
    1. 创建对象实例时
    2. 创建子类对象实例,父类也会被加载
    3. 使用类的静态成员时
  3. 普通代码块在创建对象实例时,会被隐式的调用

没完

posted @ 2022-03-14 18:06  又菜又ai  阅读(117)  评论(0)    收藏  举报