局部内部类的使用

代码走向流程:

1,实例化Outer02,调用Outer02的公共方法m1()

2,m1()方法实例化Inner02局部类

3,Inner02调用f1()方法

  • 输出局部内不类的私有属性n1,外部类需要Outer02.this.n1调用
  • 调用Outer02.this输出Outer02对象地址
  • 调用外部类的私有属性m2()

总结:

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

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

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

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

5,局部内部类定义在方法或者代码块中

6,外部其他类不能访问局部内不类(因为局部内部类地位是一个局部变量)

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

/**
 * 局部内部类
 */
public class LocalInnerClass {
    public static void main(String[] args) {
        //演示一遍
        Outer02 outer02 = new Outer02();
        outer02.m1();
        System.out.println("outer02 的 hashcode=" + outer02);
    }
}

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

    public void m1() {//方法
    //1.局部内部类是定义在外部类的局部位置,通常在方法
    //3.不能添加访问修饰符,但是可以使用 final 修饰
    //4.作用域 : 仅仅在定义它的方法或代码块中
        final class Inner02 {//局部内部类(本质仍然是一个类)
            //2.可以直接访问外部类的所有成员,包含私有的

            private int n1 = 800;

            public void f1() {
            //5. 局部内部类可以直接访问外部类的成员,比如下面 外部类 n1 和 m2()
            //7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,
            // 使用 外部类名.this.成员)去访问
            // 老韩解读 Outer02.this 本质就是外部类的对象, 即哪个对象调用了 m1, Outer02.this 就是哪个对象
                System.out.println("n1=" + n1 + " 外部类的 n1=" + Outer02.this.n1);
                System.out.println("Outer02.this hashcode=" + Outer02.this);
                m2();
            }
        }
//6. 外部类在方法中,可以创建 Inner02 对象,然后调用方法即可
        Inner02 inner02 = new Inner02();
        inner02.f1();
    }
}

匿名内部类

1.匿名内部类的使用

介绍:

1,本质是类,内部类,该类没有名字,同时还是一个对象

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

3,匿名内部类的基本语法

new 类或者接口(参数列表){

类体

};

案例:

1,基于接口的

2,基于类的

3,基于抽象类的

/**
 * 匿名内部类
 */
public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer04 outer04 = new Outer04();
        outer04.method();

    }
}

class Outer04 { //外部类
    private int n1 = 10;//属性

    public void method() {//方法

        //1,基于接口的匿名内部类
        IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("老虎叫唤...");
            }
        };
        //运行类型=class com.wyk.innerclass15.Outer04$1
        //Outer04$1 匿名内部类名字是系统分配的
        System.out.println("运行类型=" + tiger.getClass());
        //匿名内部类使用一次就不能使用了,对象可以无限使用
        tiger.cry();
        tiger.cry();
        tiger.cry();

        //2,基于类的匿名内部类
        // father1运行类型是Father
//       Father father1 = new Father("你好");
//        System.out.println(father1.getClass());
        Father father2 = new Father("你好") {
            @Override
            public void test() {
                System.out.println("你好啊!!");
            }
        };
        //father2运行类型Outer04$2
        System.out.println("father2运行类型" + father2.getClass());
        //调用方法
        father2.test();
    }

    //3,基于抽象类的匿名内部类演示
    Animal animal = new Animal(){
        @Override
        void eat() {
            System.out.println("重写抽象类的方法!!");
        }
    };



}

interface IA {//接口

    public void cry();
}

class Father {//类

    public Father(String name) {//构造器
        //传递给Father 构造器
        System.out.println("接收到 name=" + name);
    }

    public void test() {//方法
    }
}

abstract class Animal { //抽象类
    abstract void eat();
}
2. 细节

1,匿名内部类即是一个类的定义,同时本也是一个对象,因此可以调用匿名内部类方法。

2,其他使用细节和局部内部类一样。

/**
 * 匿名内部类使用细节
 */
public class AnonymousInnerClassDetail {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.method2();
    }
}

class Dog{
    private String name;
    private void method1(){
        System.out.println("小花狗");
    }

    public void method2(){
        new GG(){
            @Override
            public void gg() {
                System.out.println("重写gg");
                System.out.println(Dog.this.name);
            }

        }.gg(); //直接调用方法输出
    }
}

class GG{
  public void gg(){
      System.out.println("gg()");
  }
}
3. 当做实参直接传递
/**
 * 匿名内部类当做实参传递
 */
public class AnonymousTest {
    public static void main(String[] args) {

         a1(new Person() {
             @Override
             public void p() {
                 System.out.println("66666");
             }
         });
    }

    public static void a1(Person person) {
         person.p();
    }

}

interface Person {
    public void p();
}

成员内部类的使用

1,成员内部类调用在外部类的成员位置,并且没有static修饰。

2,可以访问外部类的所有成员,包含私有,如过外部属性和内部属性名一样可以用外部类名.this.属性名区别

3,可以添加任意访问修饰符和普通成员一样。

4,作用域:和其他成员一样整个类体

三种方法调用成员内部类

/**
 * 成员内部类
 */
public class MemberInnerClass {
    public static void main(String[] args) {
        //调用方法
//      Outer08 outer08 = new Outer08();
//        outer08.h1();
        //类调用成员内部类
//        Outer08.inner08 inner08 = outer08.new inner08();
//        inner08.say();
    
        //调用方法创建的实例
//        Outer08.inner08 inner081 = new Outer08().getInner08();
//        inner081.say();


    }
}

class Outer08 { //外部类
    private int n1 = 10;
    public String name = "张三";

    private void hi() {
        System.out.println("hi()方法...");
    }

    //成员内部类  ,可以添加任意访问修饰符 ,因为它本身就是一个成员
    public class inner08 {
        private String name;
        public void say() {
            //可以直接访问外部类的所有成员包括私有,访问外部属性 方法名.this.属性名
            System.out.println(n1 + name+Outer08.this.name);
            hi();
        }
    }

    //方法中实例对象
    public void h1() {
        inner08 inner08 = new inner08();
        inner08.say();
    }
    //返回inner08对象
  public inner08 getInner08(){
        return new inner08();
  }

}

静态内部类的使用

1,静态内部类定义在成员位置,有static修饰

2,可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员,外部属性内部属性重名时候,外部类.成员去访问,其他遵循就近原则

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

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

三种方法调用静态内部类

/**
 * 静态内部类
 */
public class StaticInnerClass01 {
    public static void main(String[] args) {
        // 调用方法实列化
//       StaticTest staticTest = new StaticTest();
//        staticTest.s3();
       //类调用静态内部类
//        StaticTest.inner09 inner09 = new StaticTest.inner09();
//        inner09.s2();

        //编写一个方法,可以返回静态内部类的对象实例.
        StaticTest.inner09 inner09 = new StaticTest().getInner09();
        inner09.s2();
    }
}

class StaticTest {
    private static String name = "你是";

    public static void s1() {
        System.out.println("静态方法s1()");
    }
    //静态内部类
    //3. 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
    //4. 可以添加任意访问修饰符(public、protected 、默认、private),因为它的地位就是一个成员
    //5. 作用域 :同其他的成员,为整个类体
    public static class inner09 {
        private static String name = "你是谁!!";

        public  void  s2() {
            System.out.println("访问外部的静态成员=" + StaticTest.name);
            System.out.println("访问内部的静态成员=" + name);
            s1();
        }
    }

    public void s3(){
        inner09 inner09 = new inner09();
        inner09.s2();
    }

    public inner09 getInner09(){
        return new inner09();
    }
}