目录

  • 1 内部类概述
  • 1.1 定义
  • 1.2 访问方式
  • 2 匿名内部类


1 内部类概述

在描述事物时,如果一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car中包含发动机类Engine,这时,Engine就可以使用内部类来描述,定义在成员位置。

1.1 定义

内部类:类B定义在类A里面,类A称为外部类,类B称为内部类。

格式:

class 外部类 {
	class 内部类 {

	}
}

示例:

class Car { // 外部类
	class Engine {// 内部类

	}
}

1.2 访问方式

  1. 内部类可以直接访问外部类的成员,包括私有成员;
  2. 外部类要访问内部类的成员,必须要建立内部类的对象。

创建内部类对象的格式

外部类名.内部类名 对象名 = new 外部类名().new 内部类名();

代码示例 :

public class Person {
	    private boolean live = true;
	    class Heart {
	        public void jump() {
	            // 直接访问外部类成员
	            if(live) {
	                System.out.println("心脏在跳动");
	            } else {
	                System.out.println("心脏不跳了");
	            }
	        }
	    }
	
	    public boolean isLive() {
	        return live;
	    }
	
	    public void setLive(boolean live) {
	        this.live = live;
	    }
	}

public class InnerDemo {
    public static void main(String[] args) {
        // 创建外部类对象
        Person p = new Person();
        // 创建内部类对象
        Person.Heart heart = p.new Heart();

        // 调用内部类方法
        heart.jump();
        // 调用外部类方法
        p.setLive(false);
        // 调用内部类方法
        heart.jump();

    }
}
心脏在跳动
心脏不跳了

2 匿名内部类

匿名内部类最好的解释

匿名内部类:是指可以利用内部类创建没有名称的对象,它一步完成了声明内部类和创建该类的一个对象,并利用该对象访问到类里面的成员。

格式:

new 父类名或接口名() {
	// 方法重写
	@Override
	public void method() {
		// 执行语句
	}
}

内部类继承一个类不需要extends修饰,实现一个接口也不需要implements,因为匿名内部类本身没有自己的名字,它的定义与创建该类的实例是同时进行的,也就是说它的前面用new运算符,而不是class关键字,用其父类名或父接口名加上一个"()"就完成了匿名对象的创建。

代码示例:

public abstract class FlyAble {
    public abstract void fly();
}

public class InnerDemo {
    public static void main(String[] args) {
		// InnerDemo是外部类
        // 1 等号右边:是一个匿名内部类对象,本质上是左边父类的一个匿名子类的对象
        // 2 等号左边:是多态赋值,父类类型引用指向匿名子类的对象
        FlyAble f = new FlyAble() {
            public void fly() {
                System.out.println("我飞了");
            }
        };

        // 调用fly方法,执行重写后的方法
        f.fly();
    }
}
我飞了
  • 在方法的形式参数是接口或抽象类时,可以将匿名内部类作为参数传递。

代码示例:

public class InnerDemo {
    public static void main(String[] args) {
        /*
        1 等号右边:是一个匿名内部类,本质上是左边父类的一个匿名子类的对象
        2 等号左边:是多态赋值,父类类型引用指向匿名子类的对象
        */

        FlyAble f = new FlyAble() {
            public void fly() {
                System.out.println("我飞了");
            }
        };

        // 将f传递给showFly方法中
        showFly(f);
    }

    public static void showFly(FlyAble f) {
        f.fly();
    }
}
我飞了

或者更加简化一步:

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

        // 创建匿名内部类,直接传递给showFly(FlyAble f)
        showFly(new FlyAble() {
            public void fly() {
                System.out.println("我飞了");
            }
        });
    }

    public static void showFly(FlyAble f) {
        f.fly();
    }
}
我飞了