内部类

语法:

  class Outer{//外部类

      class Inner{//内部类

      }

  }

  class Other{外部其他类

  }

类中的五大成员:

  属性、方法、构造器、代码块、内部类

 

内部类的分类(四种):

  a. 定义在外部类局部位置上(如在大括号里{},像方法、代码块)

    1. 局部内部类(有类名)

    2. 匿名内部类(没有类名)

  b. 定义在外部类的成员位置上(和属性、方法等位置相同)

    1. 成员内部类(没有static修饰)

    2. 静态内部类(有static修饰)

局部内部类:

public class LocalInnerClass{//5. 其他外部类不能访问局部内部类,即不能在这里实例化局部内部类对象
    public static void main(String[] args){
        Outer outer = new Outer();
        outer.m1();//调用m1方法,会实例化局部内部类inner,然后会调用f1方法
    }
}
class Outer{//外部类
    private int n1 = 10;
    public void m2(){
        System.out.println("Outer m2()...");
    }
    public void m1(){
        private int n1 = 80;
        //2. 局部内部类不能添加访问修饰符,但可以用final修饰,添加后就不能被其他内部类继承了
        //3. 作用域:局部内部类仅仅在定义它的方法或代码块中,在其他地方就使用不了
        class Inner{//局部内部类(本质还是一个类)
            public void f1(){
                System.out.println("n1="+n1 + "我i部内的n1="+Outer.this.n1);//1. 可以直接访问外部类的所有成员,包括私有的
                                            //6. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,
                                            //如果要想使用外部类的成员,可以用 外部类.this.成员 来访问
                m2();
            }
        }
        //4. 外部类怎么访问局部内部类?在外部类的方法中,可以创建Inner对象,然后再调用内部类的方法
        Inner inner = new Inner();
        inner.f1();
    }
}

匿名内部类:

   1. 本质还是一个类

·  2. 定义在外部类的局部位置(方法或代码块中)

   3. 该类没有名字(其实底层给其分配了一个名字)

   4. 是一个对象

语法:new 接口(参数列表){//这里有一个大括号,就表示定义一个匿名内部类

       类体;

   }

为什么要用匿名内部类?

  比如我们想要使用某个接口,不用匿名内部类的话,就只能再定义一个类去implement这个接口,然后再重写接口中的抽象方法,这样我们就可以new一个对象来调用接口里的方法了。然而在程序中,我们只要用实现接口的那个类一次,这样定义的这个类就会显得很冗余---》所以就要引入匿名内部类来解决这个问题

public class AnonymityInnerClass{//其他外部类
    public static void main(String[] args){
        Outer outer = new Outer();
        outer.method();//输出cring... 和testing...
    }
}

class Outer{//外部类
    private int n1 = 10;
    public void method(){
        //基于接口的匿名内部类
        //a的编译类型:A
        //a的运行类型:匿名内部类Outer$1  向上转型
        //2. 这里的new是jdk底层在创建匿名内部类Outer$1时,立即马上就创建了Outer$1实例,并把地址返回给a
        //3. 匿名内部类使用一次就不能再使用,但对象a可以在生命周期内重复使用
        A a = new A(){//1. 这里就是一个匿名内部类,定义在外部类的方法中  A a = new A(){}等价于 class Outer$1 implements A{//内部类的真实定义,Outer$01有系统分配
            public void cry(){                                                                //        public void cry(){
                System.out.println("cring...");                                                //            System.out.println("cring...");
            }                                                                                //        }         
        };                                                                                    //}
                                                                                            // A a = new Outer$01();
        a.cry();
        
        //基于类的匿名内部类
        //father的变异类型:Father
        //fathre的运行类型:匿名内部类Outer$2 ;相当于向上转型
        /*等价于 class Outer$2 extend Father(){
            public void test(){//重写了Father的方法
                System.out.println("testing...");    
            }
        }*/
        //("zhangsan")会传递给Father的构造器
        Father father = new Father("zhangsan"){//这里有大括号,就是匿名内部类;
            public void test(){//重写了Father的方法
                System.out.println("testing...");    
            }
        };
        father.test()
    }    
}

interface A{//接口
    public void cry();
}
class Father{//
    public Father(String name){//构造器
      System.out.println("Father 构造器...");
    }
    public void test(){//方法    
        System.out.println("Father testing...");
  } }

 

posted @ 2023-06-01 22:49  踏浪而来的人  阅读(4)  评论(0编辑  收藏  举报