韩顺平Java21——内部类

内部类

  • 基本介绍

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

  • 分类

局部内部类

  • 说明:
  • 局部内部类是定义在外部类的局部位置之中(比如方法或者代码块),并且有类名。

1.可以直接访问外部类的所有成员,包括私有成员。

2.不能添加访问修饰符,但是可以使用final修饰。因为它的地位就相当于一个局部变量,但本质仍然是一个类,而局部变量是不能使用访问修饰符的,但是可以使用final修饰。(就不能被其他内部类继承了)

3.作用域:仅限于定义它的方法或者代码块之中

4.局部内部类访问外部类:直接访问

5.外部类访问局部内部类:new一个对象再访问(注意需要在局部内部类的作用于之中,即该方法或者代码块中)

6.外部其他类不能访问局部内部类(因为它的地位就相当于一个局部变量)

7.如果外部类和局部内部类的成员重名时,访问遵循就近原则,如果想访问外部类的成员可以使用 (外部类名.this.属性)的方式来访问

这里的 外部类名.this 指的就是调用定义了内部类方法的外部类的对象

匿名内部类

  •  基于接口的匿名内部类:
public class Inner0 {

    public static void main(String[] args) {
        Car car = new Car();
        car.m1();
    }
}

class Car{
    public void m1(){
        IA ia=new IA(){
            @Override
            public void say() {
                System.out.println("匿名内部类重写");
            }
        };
        ia.say();
        System.out.println("ia运行类型:"+ia.getClass());//class innercalss.Car$1
    }
}

interface IA{
    void say();
}

解释:

/**底层会分配类名:Car$1
     *
     * class Car$1 implements IA{
     * @Override
     * public void say() {
     *    System.out.println("匿名内部类重写");
     * }
     *     }
     *jdk底层在创建匿名内部类Car$1的时候马上就创建了Car$1实例
     * 并且将地址返回给给 ia
     */

匿名内部类使用一次就不能再使用了,但是实例可以反复使用

  • 基于类的匿名内部类:
//基于类的匿名内部类

public class Inner001 {

    public static void main(String[] args) {
        Test test = new Test();
        test.f1();
    }
}

class Test{
    public void f1(){
        new Father("jack"){
        }.say(); //这里相当于一个对象所以可以直接.方法
    }
}

class Father{
    private String name;

    public Father(String name) {
        this.name = name;
    }
    public void say(){
        System.out.println("name="+this.name);
    }
}

  •  使用细节:

       同局部内部类

  • 最佳实现——当做实参直接传递
public class Inner01 {
//    匿名内部类最佳实现——当做实参直接传递

    public static void main(String[] args) {
        Cellphone cellphone = new Cellphone();
//        这里传递的是实现了Bell接口的匿名内部类
//        这个匿名内部类重写了ring()方法
        cellphone.alarmclock(new Bell() {
            @Override
            public void ring() {
                System.out.println("懒猪起床啦!");
            }
        });
        cellphone.alarmclock(new Bell() {
            @Override
            public void ring() {
                System.out.println("小伙伴上课啦!");
            }
        });


//传统方法 A a
= new A(); cellphone.alarmclock(a);//多态 a是实现了bell接口的类的对象
} } interface Bell { void ring(); } class Cellphone { public void alarmclock(Bell bell) { bell.ring(); } }

class A implements Bell{ @Override public void ring() { System.out.println("传统方法"); } }

成员内部类

//成员内部类

public class Inner02 {
    public static void main(String[] args) {
        Outer1 outer1 = new Outer1();
        outer1.out();
        //外部其他类使用成员内部类第一种方法 内部相当于一个成员所以可以直接.
        Outer1.Inner1 inner1 = outer1.new Inner1();

        //外部其他类使用成员内部类第二种方法
        outer1.getInner1().say();
    }
}


class Outer1 {

    private int age = 18;
    private int n1 = 10;
    private String name = "zhansgan";

    class Inner1 {
//成员内部类
private int n1 = 20; public void say() { System.out.println("age:" + age + " name:" + name+ " inner.n1="+n1+" outer.n1="+Outer1.this.n1); } } public void out() { Inner1 inner1 = new Inner1(); inner1.say(); } //外部其他类使用成员内部类第二种方法 在外部类中写一个返回值是内部类的方法 public Inner1 getInner1(){ return new Inner1(); } }
  • 注意事项:

1.成员内部类,是定义在外部类的成员位置上

2.可以添加任意访问修饰符(因为地位就是一个成员)

3.作用域:和外部类的其他成员一样,为整个类。在外部类的成员方法中创建成员内部类对象,再调用方法。

4.成员内部类访问外部类:直接访问

5.外部类访问成员内部类:new一个对象再访问

6.外部其他类访问成员内部类:两种方法(如上)

第一种是相当于把 new Inner1()当作outer1的成员,第二种方法是在外部类中写一个方法可以返回内部类对象。

7.重名同之前的

静态内部类

//静态内部类

public class Inner03 {

    public static void main(String[] args) {
        //因为是静态,所以可以通过类名直接访问
        Outer2.Inner2 inner2 = new Outer2.Inner2();
        inner2.say();

    }
}

class Outer2 {

    private int age = 18;
    static String name = "zhansgan";

    static class Inner2 {
        private int n1 = 20;
        public void say() {
            System.out.println(" name:" + name);
        }
    }

}

 

 

posted @ 2021-12-18 09:44  紫英626  阅读(73)  评论(0编辑  收藏  举报

紫英