文章目录

  • 一、成员内部类
  • 1.1 成员内部类
  • 1.2 静态内部类
  • 1.3 方法内部类
  • 1.4 匿名内部类(没有名字,隐藏名字)


一、成员内部类

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。

  • 成员内部类
  • 静态内部类
  • 方法内部类
  • 匿名内部类

1.1 成员内部类

  • 内部类中最常见的就是成员内部类,也称为普通内部类。
public class People {
    public int age;

    public Heart getHeart(){
        return new Heart();
    }

    public void eat(){
        System.out.println("人都会吃东西");
    }
    //成员内部类
    /**
     * 1、内部类在外部使用时,无法直接实例化,需要借由外部类信息才能完成实例化
     * 2、内部类的访问修饰符,可以任意,但是访问范围会受到影响
     * 3、内部类可以直接访问外部类的成员;如果出现同名属性,优先访问内部类中定义的
     * 4、可以使用外部类.this.成员的方式,访问外部类中同名的信息
     * 5、外部类访问内部类信息,需要通过内部类实例,无法直接访问
     * 6、内部类编译后.class文件命名:外部类$内部类.class
     * 7、
     */
    class Heart{
        int age =13;
        int temp =22;
        public String beat(){
            eat();
            return People.this.age + "岁的心脏在跳动";
        }
    }
}
public class PeopleTest {
    public static void main(String[] args) {
        People lili = new People();
        lili.age = 12;
        //获取内部类对象实例,方式1:new 外部类.new 内部类
        People.Heart myHeart = new People().new Heart();
        System.out.println(myHeart.beat());

        //获取内部类对象实例,方式2:外部类对象.new 内部类
        myHeart = lili.new Heart();
        System.out.println(myHeart.beat());

        //获取内部类对象实例,方式3:外部类对象.获取方法
        myHeart = lili.getHeart();
        System.out.println(myHeart.beat());

    }
}

1.2 静态内部类

静态内部类对象可以不依赖于外部类对象,直接创建。

public class People {
    public int age;

    public Heart getHeart(){
        return new Heart();
    }

    public void eat(){
        System.out.println("人都会吃东西");
    }
    //静态内部类
    /**
     * 1、静态内部类中,只能直接访问外部类的静态方法和成员,如果需要调用非静态方法和成员,可以通过对象实例
     *2、静态内部类对象实例时,可以不依赖外部类对象
     * 3、可以通过外部类.内部类.静态成员的方式,访问内部类中的静态成员
     * 4、当内部类属性与外部类属性同名时,默认直接调用内部类中的成员
     *    如果需要访问外部类的静态属性,则可以通过 外部类.属性  的方式;
     *     如果需要访问外部类中的非静态属性,则可以通过   new 外部类().属性  的方式;
     */
    public static class Heart{
        public static int age =13;
        int temp =22;
        public static void say(){
            System.out.println("hello");
        }
        public String beat(){
            new People().eat();
            return new People().age + "岁的心脏在跳动";
        }
    }
}
public class PeopleTest {
    public static void main(String[] args) {
        People lili = new People();
        lili.age = 12;
        People.Heart myHeart = new People.Heart();
        System.out.println(myHeart.beat());
        People.Heart.say();
    }
}

1.3 方法内部类

定义在外部类方法中的内部类,也称局部内部类。

  • 方法内定义的局部变量只能在方法里使用
  • 方法内不能定义静态成员
  • public、private、protected不能修饰
public class People {
    public int age;

    public Object getHeart(){
        //方法内部类
        /**
         * 1、定义在方法内部,作用范围也在方法内
         * 2、和方法内部成员使用规则一样,class前面不可以添加public,private,protected,static
         * 3、类中不能包含静态成员
         * 4、类中可以包含final,abstract修饰的成员
         */
          class Heart{
            public int age =13;
            int temp =22;
            public void say(){
                System.out.println("hello");
            }
            public String beat(){
                new People().eat();
                return new People().age + "岁的心脏在跳动";
            }
        }
       return new Heart().beat();
    }

    public void eat(){
        System.out.println("人都会吃东西");
    }
 }
public class PeopleTest {
    public static void main(String[] args) {
        People lili = new People();
        lili.age = 12;
        System.out.println(lili.getHeart());
    }
}

1.4 匿名内部类(没有名字,隐藏名字)

public abstract class Person {
    private String name;

    public Person(){

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public abstract void read();
}
public class PersonTest {
    //根据传入的不同的人的类型,调用对应的read方法
/*    //方案1:
    public void getRead(Man man){
        man.read();
    }
    public void getRead(Woman woman){
        woman.read();
    }*/
    //方案二:
    public void getRead(Person person){
        person.read();
    }
    public static void main(String[] args) {
        PersonTest test = new PersonTest();
        Man one = new Man();
        Woman two = new Woman();
        test.getRead(one);
        test.getRead(two);

        //方案三:匿名内部类
        /**
         *1、匿名内部类没有类型名称、实例对象名称
         * 2、编写后的文件命名:外部类$数字.class
         * 3、无法使用private,public,protected,abstract,static修饰
         * 4、无法编写构造方法,可以添加构造代码块
         * 5、不能出现静态成员
         *6、匿名内部类可以实现接口也可以继承父类,但是不可兼得
         */
        test.getRead(new Person() {
            @Override
            public void read() {
                System.out.println("男生喜欢看科幻类书籍");
            }
        });
        test.getRead(new Person() {
            @Override
            public void read() {
                System.out.println("女生喜欢看言情小说");
            }
        });
    }
}

匿名内部类应用场景:

  • 只用到类的一个实例
  • 类在定义后马上用到
  • 给类命名并不会导致代码更容易被理解