JAVA基础 | 内部类介绍及特点

一. 成员内部类 [了解]

注意:JDK16之前,成员内部类中不能定义静态成员。

1. 如何创建一个成员内部类?

public class Outer {
    //成员外部类
    public class Inner {
        //成员内部类
    }
}

2. 如何创建成员内部类对象?

格式:

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

public class main {
    public static void main(String[] args) {
        Outer.Inner in = new Outer().new Inner();
    }  
}

3. 如何调用成员内部类中的方法?

public class Outer {
    public class Inner {
        public void test() {
            //方法内容
        }
    }
}
public class main {
    public static void main(String[] args) {
        Outer.Inner in = new Outer.new Inner();
        in.test();
    }
}

4. 当成员外部类和成员内部类存在相同变量时该如何调用?

public class Outer {
    private int age = 99;
    public class Inner {
        private int age = 88;
        public void test() {
            int age = 77;
            System.out.println(age);    //77
            System.out.println(this.age);    //88
            System.out.println(Outer.this.age);    //99
        }
    }
}

二. 静态内部类 [了解]

1. 如何创建一个静态内部类

参照成员内部类,只需要在定义成员内部类的时候在前面加上static关键词修饰

public class Outer {
    ///静态内部类
    public static class Inner {
        //类内容
    }
}

2.如何创建静态内部类对象?

格式:

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

public class Main() {
    public static void main(String[] args) {
        Outer.Inner in = new Outer.Inner();
    }
}

3. 静态内部类中访问外部类成员的特点

可以直接访问外部类的静态成员,不可以直接访问外部类的实例成员。

三. 局部内部类 [了解]

局部内部类是定义在方法中,代码块中,构造器等执行体中的类。

黑马老师提醒:鸡肋语法,看看就好

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

    public static void go() {
        class A {
            
        }
        
        abstract class B {
        
        }
        
        interface C {
            
        }
    }
}

四. 匿名内部类 [重要]

定义:一种特殊的局部内部类,所谓匿名,指的是程序员不需要为这个类声明名字

匿名类本质就是一个字类,而且会立即创建一个字类对象。

new 类或接口(参数值..) {

        类体(一般是方法重写);

};

1. 了解匿名内部类

首先,我们通过一个例子来了解什么是匿名内部类呢?请看下面的代码:

public class Main {
    public static void main(String[] args) {
        Animal a = new Cat();
        a.cry();
    }
}

class Cat extends Animal {
    @Override
    public void cry {
        System.out.println("喵喵叫~~~~");
    }
}

abstract class Animal {
    public abstract void cry();
}

在上面的实例中,我们定义了一个Animal类,并在其中添加了抽象方法cry,此时,如果我们想添加一个Cat类,让Cat继承Animal类,并在cry时发出”喵喵叫~“,就需要在Main类之外定义一个Cat类,再去这个里面写cry方法,然后去Main中创建对象并调用cry方法,这种实现过程比较复杂,所以我们引入”匿名内部类“,请看下文:

public class Main {
    public static void main(String[] args) {
        Animal a = new Animal() {
            @Override
            public void cry() {
                System.out.println("小猫喵喵叫~~");
            }
        };
        a.cry();
    }
}

abstract class Animal {
    public abstract void cry();
}

怎么样,代码是不是简化了很多?这里所用到的,就是匿名内部类!

2. 匿名内部类的常见使用场景

1. 通常作为一个参数传输给方法。

请看下面的代码:

public class Main {
    public static void main(String[] args) {
        Swimming s1 = new Swimming() {
            @Override
            public void swim() {
                System.out.println("狗游得快");
            }
        };
        go(s1);
    }

    //设计一个方法,可以接收swimming接口的一切实现类对象进来参加游泳比赛
    public static void go(Swimming s) {
        System.out.println("开始--------------------");
        s.swim();
    }
}

//猫和狗都要参加游泳比赛
interface Swimming {
    void swim();
}

在上述情况中,我们创建一个s1对象,并在里面写上独有的“狗游泳”方法,再将s1传递给go方法。

而实际上我们可以直接将整个s1作为一个参数进行传输,如下:

public class Main {
    public static void main(String[] args) {
        go(new Swimming() {
            @Override
            public void swim() {
                System.out.println("狗游得快");
            }
        });
    }

    //设计一个方法,可以接收swimming接口的一切实现类对象进来参加游泳比赛
    public static void go(Swimming s) {
        System.out.println("开始--------------------");
        s.swim();
    }
}

//猫和狗都要参加游泳比赛
interface Swimming {
    void swim();
}

2. 实际运用

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Test {
    public static void main(String[] args) {
        //扩展: 搞清楚匿名内部类在开发中的真实使用场景
        //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) {
                JOptionPane.showMessageDialog(win,"登陆一下");
            }
        });

        win.setSize(400,400);
        win.setLocationRelativeTo(null);    //居中
        win.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        win.setVisible(true);
    }
}

在后面的内容中,将会学到新的知识来简化这种语法:

import javax.swing.*;

public class Test {
    public static void main(String[] args) {
        //扩展: 搞清楚匿名内部类在开发中的真实使用场景
        //1. 创建窗口
        JFrame win = new JFrame("登陆界面");
        JPanel panel = new JPanel();
        win.add(panel);

        JButton btn = new JButton("登陆");
        panel.add(btn);

        //给按钮绑定单击事件监听器
        btn.addActionListener(e -> JOptionPane.showMessageDialog(win,"登陆一下"));

        win.setSize(400,400);
        win.setLocationRelativeTo(null);    //居中
        win.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        win.setVisible(true);
    }
}

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值