15Java基础之内部类
内部类
- 内部类是类中五大成分之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类。
- 场景:当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。
![image]()
内部类有四种形式
- 成员内部类
- 就是类中的一个普通成员,类似我们学过的普通的成员变量、成员方法。
![image]()
注意:JDK16之前,成员内部类中不能定义静态成员,JDK16开始才可以定义静态成员了。
创建内部成员对象的格式:
外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
Outer.Inner in = new Outer().new Inner();
成员内部类的特点:
- 无static修饰,属于外部类的对象持有的
- 必须存在外部类对象,才会有这个内部类
- 拓展:成员内部类访问外部类的成员特点
- 成员内部类的实例方法中,是可以直接访问外部类的实例成员、静态成员的。
- 成员内部类的实例方法中,拿到当前外部类对象,格式是:外部类名.this。
案例:
// 外部类
public class Outer {
public static String schoolName = "霍格沃兹";
public static void inAdder(){
System.out.println("我是外部类的静态方法");
}
private String hobby;
private double height;
public void run(){
System.out.println("run");
}
// 成员内部类
// 特点:无static修饰,属于外部类的对象持有的
// 必须存在外部类对象,才会有这个内部类
public class Inner{
private String name;
private int age;
public Inner() {
}
public Inner(String name, int age) {
this.name = name;
this.age = age;
}
//拓展:成员内部类访问外部类的成员特点
public void show(){
System.out.println("我是成员内部类的方法");
// 成员内部类中,是可以直接访问外部类的静态成员的
System.out.println(schoolName);
inAdder();
// 成员内部类中,可以直接访问外部类的实例对象。
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}
测试:
// 目标:掌握成员内部类,搞清楚语法即可。
public class Test {
public static void main(String[] args) {
//创建外部类对象
Outer out = new Outer();
//创建内部类对象
//格式:外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
Outer.Inner in = new Outer().new Inner();
in.show();
}
}
- 静态内部类
- 有static修饰的内部类,属于外部类自己持有。
![image]()
创建对象的格式:
- 外部类.内部类 对象名 = new 外部类名.静态内部类名();
Outer.Inner in = new Outer.Inner();
静态内部类中的访问外部类成员的特点
- 可以直接访问外部类的静态成员,不可以直接访问外部类的实例成员。
案例:
//外部类
public class Outer {
public static String schoolName = "霍格沃兹";
public static void inAdder(){
System.out.println("我是外部类的静态方法");
}
private String hobby;
private double height;
public void run(){
System.out.println("run");
}
//静态内部类:static修饰,属于外部类本身
public static class Inner{
// 类有的成员它都有
private String name;
private int age;
public Inner() {
}
public Inner(String name, int age) {
this.name = name;
this.age = age;
}
public void show(){
System.out.println("我是成员静态内部类的方法");
// 1. 静态内部类中,是可以直接访问外部类的静态成员。
System.out.println(schoolName);
inAdder();
// 2. 静态内部类中,是不可以直接访问外部类的实例成员
//System.out.println(hobby); // 报错
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}
测试:
// 目标:认识静态内部类,搞清楚其特点
public class Test {
public static void main(String[] args) {
// 静态内部类的定义
// 外部类.内部类 对象名 = new 外部类名.new 静态内部类名();
Outer.Inner in = new Outer.Inner();
in.show();
}
}
- 局部内部类
- 局部内部类是定义在方法中、代码块中、构造器等执行体中。
案例:
//目标:了解局部内部类,定义在方法里,构造器里,代码块里等局部范围里的类。
public class Test {
public static void main(String[] args) {
// 局部内部类(鸡肋语法)
class A{
public void show(){
System.out.println("我是局部内部类的方法");
}
}
A a = new A();
a.show();
}
}
- 匿名内部类(重点)
- 就是一种特殊的局部内部类。所谓的匿名:指的是程序员不需要为这个类声明名字。
![image]()
- 特点:匿名内部类本质就是一个子类,并会立即创建出一个子类对象。
- 作用:用于更方便的创建一个子类对象。
案例:
// 目标:认识匿名内部类
public class Test {
public static void main(String[] args) {
// 匿名内部类本质是一个子类,同时会立即创建一个子类对象
Animal a = new Animal(){
@Override
public void cry() {
System.out.println("狗是汪汪的叫~");
}
};
a.cry();
}
}
/*
class Dog extends Animal{
@Override
public void cry() {
System.out.println("狗是汪汪的叫~");
}
}
*/
abstract class Animal{
public abstract void cry();
}
匿名内部类的常见使用场景
- 通常作为一个参数传输给方法。
案例:
需求:学生和老师一起参加游泳比赛
//目标:匿名内部类的使用场景,通常作为一个对象参数传递给方法使用
public class Test {
public static void main(String[] args) {
// 创建匿名内部类
Swimming s = new Swimming() {
@Override
public void swim() {
System.out.println("学生游泳贼快!");
}
};
goSwimming(s);
goSwimming(new Swimming() {
@Override
public void swim() {
System.out.println("老师游的贼慢~");
}
});
}
public static void goSwimming(Swimming s){
System.out.println("开始。。。");
s.swim();
System.out.println("结束了。。。");
}
}
//需求:学生和老师一起参加游泳比赛
interface Swimming{
void swim();
}
匿名类的拓展
案例:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
// 拓展:掌握匿名内部类的真实场景。
public class Test2 {
public static void main(String[] args) {
//GUI SWING编程:桌面编程
//1. 创建一个窗口
JFrame win = new JFrame("登录");
// 创建一个桌布
JPanel panel = new JPanel();
win.add(panel);
JButton btn = new JButton("登录");
panel.add(btn);
// 给按钮绑定单击事件监听器对象,可以用来监听用户的点击,以便做出反应。
// 匿名内部类是作为一个对象参数传输给方法使用的,至于什么时候用匿名内部类要看实际开发需求。
// 遇到了才用,没有遇到就不用了。
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("点击我,我要登录!");
JOptionPane.showMessageDialog(win, "没事别点我!");
}
});
//2. 设计大小,居中显示
win.setSize(400, 300);
win.setLocationRelativeTo(null);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
}
}





浙公网安备 33010602011771号