Java基础——内部类和匿名内部类

一、内部类
1、概述

  • 把类定义在其他类的内部

2、内部类的访问特点

  • 内部类可以直接访问外部类的成员,包括私有
  • 外部类要访问内部类的成员,必须创建对象
class Outer{
    private int num = 10;
    class Inner{//内部类
        public void show(){//内部类成员方法
            System.out.println("这是内部类是 show 方法");
        }
    }
    public void method(){//成员方法
        Inner in = new Inner();//创建对象,new 出内部类的成员方法
        in.show();
    }
}

public class InnerClassDemo {
    public static void main(String[] args){
        Outer ou = new Outer();//实例化外部类的成员方法
        ou.method();//输出:这是内部类是 show 方法
    }
}

二、成员内部类
1、按照内部类在类中的定义位置:

  • 成员位置(成员内部类)
  • 局部位置(局部内部类)
class Outer{
    private int num = 10;
    class Inner1{//在成员位置,成员内部类
        public void show(){//内部类成员方法
            System.out.println("这是内部类是 show 方法");
        }
    }
    public void method(){//成员方法
        class Inner2{//在局部的位置,局部内部类
            public void method(){
                System.out.println("这是局部内部类的 method 方法");
            }
        }
    }
}

public class InnerClassDemo {
    public static void main(String[] args){
        
    }
}

在这里插入图片描述

2、成员内部类,外界如何创建对象(一般内部类就是不让外界访问)

  • 外部类名.内部类名 对象名 = 外部类对象.内部类对象
  • Outer.Inner in = new Outer().new Inner();
class Outer{
    private int num = 10;
    class Inner{//在成员位置,成员内部类
        public void show(){
            System.out.println("在成员方法的位置,成员内部类,show方法");
        }
    }
}
public class InnerClassDemo{
    public static void main(String[] args){
        //需求:访问成员内部类的 show 方法
        Outer.Inner in = new Outer().new Inner();//注意书写
        in.show();
    }
}

3、成员内部类,常见修饰符

  • private 为了保证数据的安全性
  • 为了让数据访问更方便

4、注意:静态内部类访问的外部类数据必须用静态修饰。

class Outer{
    private int num1 = 10;
    private static int num2 = 20;
    public static class Inner{//静态成员内部类,
        public void show1(){
            //System.out.println("内部类里的 show 方法"+num1);//静态内部类访问外部类数据,外部数据必须静态修饰,无法访问num1
            System.out.println("内部类里的 show 方法"+num2);//可以访问 num2 的值,因为 num2 被静态修饰
        }
        public static void show2(){
            //System.out.println("内部类里的 show 方法"+num1);
            System.out.println("内部类里的 show 方法"+num2);//可以访问外部类的 num2 的值
        }
    }
}
class InnerClassDemo{
    public static void main(String[] args){
        //使用静态内部类,下面这个是错误的
//        Outer.Inner in1 = new Outer().new Inner();
//        in1.show1();
//        in1.show2();
        Outer.Inner in2 = new Outer.Inner();//成员内部类被静态修饰后的访问方式
        in2.show1();
        in2.show2();
        //Outer.Inner.show1();//无法调用,内部类 Inner 的show1 方法没有被静态修饰
        Outer.Inner.show2();//可以调用
    }
}

三、局部内部类

1、按照内部类在类中的定义位置:

  • 成员位置(成员内部类)
  • 局部位置(局部内部类)

2、局部内部类特点

  • 可以直接访问外部类的成员
  • 可以创建内部类对象,通过对象调用内部类方法,来使用内部类

3、局部内部类访问局部变量必须用 final 修饰

  • 因为局部变量会随着方法的调用完毕而消失,这时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,就用 final 修饰,这样,在堆内存里面就是一个常量。
class Outer{
    private int num1 = 10;
    public void show(){
        int num2 = 20;
        final int num3 = 30;
        class Inner{
            public void method(){
                System.out.println(num1);//可以直接访问外部类的成员变量
                System.out.println("_________");
                System.out.println(num2);
                System.out.println(num3);
            }
        }
        System.out.println(num2);
        System.out.println(num3);
        Inner in1 = new Inner();
        in1.method();
    }
}
class InnerClassDemo{
    public static void main(String[] args){
        Outer ou1 = new Outer();
        ou1.show();
    }
}

四、匿名内部类

1、概述

  • 内部类的简化写法

2、前提

  • 存在一个类或者接口(可以是具体类或者是抽象类)

3、格式

  • new 类名(){重写方法}

4、本质

  • 是一个继承了类或者实现了接口的子类匿名对象

5、实例

局部内部类是实现(普通写法)

interface Jiekou{
    void show();//接口里的成员方法必须是抽象方法,后面不能有 {} ,默认可以省略 public abstract
}
public class InnerClassDemo{
    public void method(){
        class Inner implements Jiekou{//局部内部类实现接口
            public void show(){
                System.out.println("局部内部类实现 show 方法");
            }
        }
        Jiekou j = new Inner();//多态
        j.show();
    }
    public static void main(String[] args){
        InnerClassDemo in = new InnerClassDemo();
        in.method();//输出:局部内部类实现 show 方法
    }
}

使用匿名内部类,局部内部类是实现

interface Jiekou{
    void show();//接口里的成员方法必须是抽象方法,后面不能有 {} ,默认可以省略 public abstract
}
public class InnerClassDemo{
    public void method(){
        //使用局部内部类的实现
//        class Inner implements Jiekou{//局部内部类实现接口
//            public void show(){
//                System.out.println("局部内部类实现 show 方法");
//            }
//        }
//        Jiekou j = new Inner();//多态
//        j.show();
        //使用匿名内部类的实现
        //接口用于匿名内部类的时候是可以实例化的
        Jiekou j = new Jiekou() {
            @Override
            public void show() {
                System.out.println("匿名内部类的实现 show 方法");
            }
        };
        j.show();

    }
    public static void main(String[] args){
        InnerClassDemo in = new InnerClassDemo();
        in.method();
    }
}

注意:

  • 上面两种方法是等价的

猜你喜欢

转载自blog.csdn.net/weixin_43860260/article/details/91335564