概述
定义
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
种类
成员内部类 匿名内部类(重点)
成员内部类(定义在类中方法外的类)
定义格式
class 外部类 {
class 内部类 {
}
}
在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽⻋类 Car 中包含发动机类 Engine ,这时, Engine 就可以使用内部类来描述,定义在成员位置。
代码举例
class Car {
//外部类
class Engine {
//内部类
}
}
访问特点
1.可以直接访问外部类的所有成员,包含私有的
2.可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
3.作用域和外部类的其他成员一样,为整个类体,在外部类的成员方法中创建成员内部类对象,再调用方法.
4.成员内部类—访问---->外部类成员(比如;属性)[访问方式:直接访问]
5.外部类—访问------>成员内部类 访问方式:创建对象,再访问
6.外部其他类—访问---->成员内部类
7.如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
创建内部类对象格式:
外部类名.内部类名 对象名 = 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(); // 创建内部类对象
Heart heart = p.new Heart();
// 调用内部类方法
heart.jump();
// 调用外部类方法
p.setLive(false);
// 调用内部类方法
heart.jump();
}
}
输出结果:
心脏在跳动
心脏不跳了
匿名内部类
定义
是内部类的简写。它的本质其实是一个带着具体实现父类或者父接口的匿名的子类对象
前提:匿名内部类必须【继承一个父类】或者【实现一个接口】,伴随着重写父类或者父接口当中抽象方法
解释
开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作:
1. 定义子类
2. 重写接口中的方法
3. 创建子类对象
4. 调用重写后的方法
我们的目的,最终只是为了调用方法,那么能不能简化一下,把以上四步合成一步呢?匿名内部类就是做这样的快捷方式。
格式
new 父类名或者接口名() {
// 方法重写
@Override
public void method() {
// 执行语句
}
};
使用方式
以接口为例,匿名内部类的使用,代码如下:
定义接口:
public abstract class FlyAble {
public abstract void fly();
}
创建匿名内部类,并调用:
public class InnerDemo {
public static void main(String[] args) {
/*
* 1.等号右边:是匿名内部类,定义并创建该接口的子类对象
* 2.等号左边:是多态赋值,接口类型引用指向子类对象
*/
FlyAble f = new FlyAble() {
public void fly() {
System.out.println("我⻜了~~~");
}
};
// 调用fly方法,执行重写后的方法
f.fly();
}
}
通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。代码如下:
public class InnerDemo2 {
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 InnerDemo3 {
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();
}
}