内部类

基本介绍

内部类是类的五大成员之一。
一个类的内部完整嵌套了另一个类结构。被嵌套的类称作内部类,嵌套其它类的类叫做外部类。

class Outer {// 外部类

    class Inner {} //内部类
}

class Other {}// 其他类

 内部类的分类

定义在外部类局部位置上, 如方法内:

  1. 局部内部类(有类名)
  2. 匿名内部类(无类名)

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

  1. 成员内部类(无static修饰)
  2. 静态内部类(有static修饰)

局部内部类

  1. 可以直接访问外部类的所有成员,包含私有的。
  2. 不能添加访问修饰符,因为他就是一个局部变量,但可以用final修饰
  3. 作用域:仅在定义它的方法或代码块中。
  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() {//方法
        final class Inner02 {
            private int n1 = 800;
            public void f1() {
                System.out.println("n1=" + n1 + " 外部类的n1=" + Outer02.this.n1);
                System.out.println("Outer02.this hashcode=" + Outer02.this);
                m2();
            }
        }
        Inner02 inner02 = new Inner02();
        inner02.f1();
    }
}

小结: 局部类定义在方法或代码块中;作用域在方法体或代码块中;本质还是类。

匿名内部类

引出:为了简化开发创建基于接口或一个类去创建一个新类,这个类只用一次就不再用。

是一个没有名字的内部类;同时还是一个对象;

基本语法:new 类或者接口(参数列表){类体}; 

基于接口的匿名内部类
public class AnonymousInner {
    public static void main(String[] args) {
    Outer outer =new Outer();
    outer.method();
    }
}

class Outer {
    private int n1 = 10;
    public void method() {
        //只是用一次的类,不需要这样实现
        /*A dog =new Dog();
        dog.cry();*/
        // 创建匿名内部类Quter$1后立刻就创建了Quter$1,实例并把地址返回给dog
        A dog= new A(){
            public void cry() {
                System.out.println("狗叫中。。。");

            }
        };
        dog.cry();
        // 匿名类运行底层会分配类名Outer$1
        System.out.println("dog的运行类型是"+dog.getClass());
    }
}
//仅使用一次的类就需要定义一次,后续不再使用;选择使用匿名内部类简化
/*class Dog implements A{
    @Override
    public void cry() {
        System.out.println("狗叫中。。。");
    }
}*/

interface A {
    public void cry();
}
基于类的匿名内部类
public class Annoy {
    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        outerClass.function();
    }
}

class OuterClass {
    public void function() {
        //参数列表会传递给构造器
        Father father = new Father("jack") {
            @Override
            public void test() {
                System.out.println("匿名内部类重写了test方法");
            }
        };
        System.out.println("father的运行类型="+father.getClass());
        father.test();
        // 基于抽象类的匿名内部类
        B b=new B() {
            @Override
            public void need() {
                System.out.println("基于抽象类的匿名内部类实现了抽象类B");
            }
        };
        b.need();
    }
}

interface A {       // 接口
    public void run();
}

class Father {
    public Father(String name) {
        System.out.println("接收到的name="+name);
    }

    public void test() {
    }
}
abstract class B{
    public void need(){
        System.out.println("这是一个抽象类");
    }
}
硬编码和使用匿名内部类
public class Annoy {
    public static void main(String[] args) {
        //匿名函数的实现方法
        f1(new A() {
            @Override
            public void show() {
                System.out.println("this is show()");
            }
        });
        //硬编码的方式实现
        f1(new B());
    }
    public static void f1(A a){
        a.show();
    }
}
interface A{
    void show();
}
// 硬编码,通过一个类实现接口后再被调用
class B implements A{
    @Override
    public void show() {
        System.out.println("2.this is show()");
    }
}
匿名内部类使用演示
 public class Annoy {
    public static void main(String[] args) {
        alarmClock(new Bell() {
            @Override
            public void ring() {
                System.out.println("懒猪起床");
            }
        });
        alarmClock(new Bell() {
            @Override
            public void ring() {
                System.out.println("上课了");
            }
        });
    }

    public static void  alarmClock(Bell bell) {
        bell.ring();
    }
}

interface Bell {
    void ring();
}

class CellPhone {
    public void alarmclock(Bell bell) {
        bell.ring();
        CellPhone cellPhone = new CellPhone() {
        };
    }
}

成员内部类

成员内部类是定义在外部类的成员位置的无static修饰;可以直接访问外部类的所有成员。

成员内部类定义在外部类的内部成员位置上;可以添加任意修饰符。

作用域:和外部类的其他成员一样(整个类体)

  1. 内部成员类访问外部成员:直接访问。
  2. 外部类访问内部类:先创建对象,再访问;
  3. 外部其他类使用成员内部类的两种方式,(1)把内部类当做是外部类的成员(2)外部类编写方法返回内部对象实例

外部类和内部类成员重名时,内部类访问遵守就近原则,访问外部类使用(外部类名.this.成员)访问

成员内部类
class Outer {
    private int num = 9;
    public String name = "rick";

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

    class Inner {
        public int num=99;
        public void say() {
            System.out.println("使用了成员内部类");
            System.out.println("Outer的num=" + num + "Outer的name=" + name);
            hi();
            Inner inner = new Inner();

            System.out.println("外部类的属性num="+Outer.this.num);
            System.out.println("内部类的属性num="+inner.num);
            System.out.println(num);
        }

    }
    public Inner getInner(){
        return  new Inner();
    }
    public void test() {
        // 使用成员内部类 new内部类对象,然后使用相关属性或方法
        Inner inner = new Inner();
        inner.say();
    }
}

静态内部类

定义在外部类成员位置且有static修饰;可以访问外部类的所有静态成员(不能访问非静态成员),可以添加任意修饰符。作用域:整个类体。

  1. 静态内部类访问外部类的访问方式是是直接访问所有静态成员
  2. 外部类访问静态内部类是先创建对象,再访问
  3. 静态内部类可以通过类名直接访问(满足访问权限)
  4. 外部类与静态内部类成员重名,默认遵守就近原则,访问外部类成员使用(外部类名.成员)。
静态内部类
 public class StaticInner {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.fun1();
        // 外部其他类使用静态内部类,方法1.
        Outer.Inner inner = new Outer.Inner();
        inner.say();
        // 方法2.
        Outer.Inner inner1 = outer.getInner();
        inner1.say();
        // 方法3.利用静态特点。
        Outer.Inner inner2 = Outer.StaticGetInner();
    }
}

class Outer {
    private int num = 8;
    private static String name = "rick";

    private static void run() {
    }

static class Inner {
        static String name = "Inner's rick";

        public void say() {
            System.out.println(name + " say some thing");
            System.out.println(Outer.name + " say some thing");
        }
    }

    public void fun1() {
        Inner inner = new Inner();
        inner.say();
        run();
    }

    public Inner getInner() {
        return new Inner();
    }

    public static Inner StaticGetInner() {
        return new Inner();
    }
}

 

posted @ 2024-04-03 23:36  Dr丶云幕  阅读(4)  评论(0编辑  收藏  举报