Java基础重点之四大内部类

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

一、局部内部类
声明名在外部内的方法或代码块中,局部内部类可以直接使用外部内私有的属性,可以声明自己局部内部类的属性和方法,跟外部类一样可以由类的五大成员变量变量组成,不能添加访问修饰符,因为局部内部类的地位等同于局部变量。局部变量是不能使用修饰符的;当内部类和外部内有同名属性时,访问这个属性会遵循就近原则,若需要访问外部类同名属性,可以使用外部类名.this.属性名进行访问;局部内部类不能被外部内new,只能在当前方法中使用。
代码示例:

package com.example.springdemo.study.内部类;

/**
 * @author zhangsm
 * @since 2023/12/26
 */
public class Student {

    private String name = "张三";
    private String age;

    public void printStudentName() {
        class Jack {
            String name = "李四";

            public void printJack() {
                //访问内部类的name
                System.out.println(this.name);
                //访问外部类name
                System.out.println(Student.this.name);
            }
        }
        Jack jack = new Jack();
        jack.printJack();
    }
}

class TestStudent {
    public static void main(String[] args) {
        new Student().printStudentName();
    }
}

二、匿名内部类
匿名内部类只会被创建一次,也能只能被使用一次,使用完后就会被销毁;
代码示例:

package com.example.springdemo.study.匿名内部类;

/**
 * @author zhangsm
 * @since 2023/12/26
 */
public class AnonymousClassDemo {
    public static void main(String[] args) {
        new OuterClass().anonymousClass();
    }
}


interface MyAnimal {
    MyAnimal eat();
    void smile();

}

//外部类
class OuterClass {
    public void anonymousClass() {
        //匿名内部类
        new MyAnimal() {
            @Override
            public MyAnimal eat() {
                System.out.println("小狗吃骨头");
                System.out.println(this);
                return this;
            }
            @Override
            public void smile() {
                System.out.println("小狗在微笑");
                System.out.println(this);
            }
        }.eat().smile();
        //打印可得到真实的匿名内部类的编译类型为MyAnimal$1
//        System.out.println(myAnimal.getClass());
    }
}

PS:经典使用场景,作为入参传递
代码示例:

public class AnonymousClassDemo {
    public static void main(String[] args) {
        new OuterClass().anonymousClass();
    }
}

interface MyAnimal {
    MyAnimal eat();
    void smile();
}
//外部类
class OuterClass {
    public void testAnonymousClass(MyAnimal myAnimal) {
        System.out.println(myAnimal.eat());
    }

    public void test() {
        testAnonymousClass(new MyAnimal() {
            @Override
            public MyAnimal eat() {
                System.out.println("测试匿名内部类入参重写eat");
                System.out.println(this);
                return this;
            }

            @Override
            public void smile() {
                System.out.println("测试匿名内部类入参重写smile");
                System.out.println(this);
            }
        });
    }
 }

三、成员内部类
声明在外部类中,可以看成是一个外部类的成员变量,因此成员内部类是可以用访问修饰符进行修饰的,访问规则跟外部类一致;成员内部类也可以定义自己的类的五大成员;当内部类和外部内有同名属性时,访问这个属性会遵循就近原则,若需要访问外部类同名属性,可以使用外部类名.this.属性名进行访问;当成员内部类的访问权限允许的条件下,是可以被外部类new的。

代码示例:

/**
 * 1.局部内部类只能被当前方法使用,不能用访问修饰符修饰->局部内部类可以定义在方法里也可以是匿名内部类
 * 2.
 *
 * @author zhangsm
 * @since 2023/12/21
 */
 //外部类
public class Other {
    private String name = "张三";
    //静态成员内部类
    public class A {
        public int a = 1;
        //内部类的内部类
        protected class B {
        //Other.A.B的实例方法print()
            public void print(){
                System.out.println("hhhhhhh我是嵌套的成员内部类");
            }
        }
    }
    //Other的实例方法print()
    public void print() {
        class C {
            private String name = "李四";
            public void CPrint() {
                System.out.println("我是局部内部类");
            }
            public void CPrint2() {
                System.out.println(Other.this.name);
                System.out.println(this.name);
            }
        }
        new C().CPrint2();
    }
}

class Test{
   public void main(String[] args){
   //创建成员内部类实例的方式
   Other.A a = new Other().new A();
   Other.A.B b = new Other().new A().new B();
   //使用成员内部类的方法
   b.print();
   }
}

四、静态内部类
静态内部类定义在类的成员位置,关键字static修饰i,静态内部类可以直接访问外部类的静态成员属性和静态方法(包括私有的静态属性和私有的静态方法),但不能直接访问非静态的成员属性和非静态方法,需要创建一个外部的类实例对象才能够对其进行访问。作用域为整个外部类类体。当静态内部类被声明为私有的时候,是无法像普通的私有变量一样提供一个公共方法方法访问到的(可尝试把示例代码的静态内部类声明为private)
代码示例:

package com.example.springdemo.study.静态内部类;

/**
 * @author zhangshunmin
 * @since 2023/12/27
 */
public class OuterClass {
    private String name = "张三";
    private static int age = 10;

    static class StaticInnerClass {
        public void print() {
            //直接访问非静态属性报错
//            System.out.println(name);
            //编译通过
            System.out.println(age);

            OuterClass outerClass = new OuterClass();
            System.out.println(outerClass.name);
        }
    }
    public static StaticInnerClass getStaticInnerClass(){
        return new getStaticInnerClass();
    }
}

//外部其他类
class Test {
    public static void main(String[] args) {
        OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass();
        staticInnerClass.print();
        //当静态内部类被声明为私有的时候下面代码报错;
       // OuterClass.StaticInnerClass staticInnerClass2 =  OuterClass.getStaticInnerClass();
    }
}

你可能感兴趣的:(恶补Java基础,java)