Java基础 第二节 第十九课
概述
什么是内部类
将一个类 A 定义在另一个类 B 里面, 里面的那个类 A 就称为内部类, B 则称为外部类.
成员内部类
成员内部类: 定义在类中方法外.
定义格式:
class 外部类 {
class 内部类{
}
}
- 1
- 2
- 3
- 4
在描述事物时, 若一个事物内还包含其他事物, 就可以使用内部类这种结构. 比如, 汽车类 Car 中包含发动机类 Engine. 这时, Engine 就可以使用内部类来描述, 定义在成员位置.
代码实现:
class Car { // 外部类
class Engine { // 内部类
}
}
- 1
- 2
- 3
- 4
访问特点
- 内部类可以直接访问外部类的成员, 包括私有成员
- 外部类要访问内部类的成员, 必须要建立内部类的对象
创建内部类对象格式:
外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
- 1
访问演示, 代码如下:
定义类
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 this.live;
}
public void setLive(boolean live) {
this.live = live;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
定义测试类
public class Test {
public static void main(String[] args) {
// 创建外部类对象
Person person = new Person();
// 创建内部类对象
Person.Heart heart = person.new Heart();
// 调用内部类方法
heart.jump();
// 调用外部类方法
person.setLive(false);
// 调用内部类方法
heart.jump();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
执行结果:
注: 内部类任然是一个独立的类, 在编译之后, 内部类会被编译成独立的 .class 文件. 但是前面冠以外部类的类名和 $ 符号.
匿名内部类
匿名内部类: 是内部类的简化写法. 它的本质是一个带具体实现的父类或者父亲接口的匿名的子类对象.开发中, 最常用到的内部类就是匿名内部类了.
以接口举例, 当你使用一个接口时, 都会进行如下几步操作:
- 定义子类
- 重写接口中的方法
- 创建子类对象
- 调用重写后的方法
我们的目的, 最终是为了调用方法, 那么能不能简化一下, 把以上四步合成一步呢? 匿名内部类就是做这样的快捷方式.
前提
匿名内部类必须继承一个父类或者实现一个父类接口.
格式
new 父类方法或者接口名() {
// 方法重写
@Override
public void method() {
// 执行语句
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
使用方式
以接口为例, 匿名内部类的使用, 代码如下:
定义接口
public abstract class FlyAble {
public abstract void fly();
}
- 1
- 2
- 3
调用方法1
创建匿名内部类, 并调用:
public class Test {
public static void main(String[] args) {
/**
* 等号右边: 是匿名内部类, 定义并创建该接口的子类对象
* 等号左边: 是多态赋值, 接口类型引用指向子类对象
*/
FlyAble flyAble = new FlyAble() {
@Override
public void fly() {
System.out.println("我飞了");
}
};
// 调用fly方法, 执行重写后的方法
flyAble.fly(); // 输出结果: 我飞了
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
调用方法2
当方法的形式参数是接口或者抽象雷士, 可以把匿名内部类作为参数传递:
public class Test {
public static void main(String[] args) {
/**
* 等号右边: 是匿名内部类, 定义并创建该接口的子类对象
* 等号左边: 是多态赋值, 接口类型引用指向子类对象
*/
FlyAble flyAble = new FlyAble() {
@Override
public void fly() {
System.out.println("我飞了");
}
};
// 将flyAble传递给showFly方法中
showFly(flyAble); // 输出结果: 我飞了
}
public static void showFly(FlyAble f) {
f.fly();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
调用方法3
以上两种方法, 也可以简化为一步:
public class Test10 {
public static void main(String[] args) {
// 创建匿名内部类, 直接传递给showFly(Flyable f)
showFly(new FlyAble() {
@Override
public void fly() {
System.out.println("我飞了");
}
});
}
public static void showFly(FlyAble f) {
f.fly();
}
}
输出结果:
我飞了
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
文章来源: iamarookie.blog.csdn.net,作者:我是小白呀,版权归原作者所有,如需转载,请联系作者。
原文链接:iamarookie.blog.csdn.net/article/details/110182974
- 点赞
- 收藏
- 关注作者
评论(0)