内部类
内部类是什么?
字面意思,在类的内部编写的类就叫内部类!即一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。
内部类是类的第五大成员→【提示:类的五大成员是哪些?[属性、方法、构造器、代码块、内部类]】
一、成员内部类
(在类的内部方法的外部编写的类就是成员内部类)
成员内部类特点:
1.成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员);
2.同名的属性名/方法名访问外部类时 → 外部类.this.成员名
Outer.this.name
public class Test {
public static void main(String[] args) {
Outer.Inner in =new Outer().new Inner();
in.test();
}
}
public class Outer {
private int age=99;
public static String a;
public class Inner{
private String name;
public static String SchoolName;//jdk16才开始定义静态成员变量
private int age=88;
public void test(){
System.out.println(a);
System.out.println(age);
int age =66;
System.out.println(age);//66
System.out.println(this.age);//88
System.out.println(Outer.this.age);//99
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public void test2(){
System.out.println(a);
System.out.println(age);
}
}
二,静态内部类
(在类中编写的以static修饰的类称为静态内部类)
静态内部类特点
Inner
类被声明为静态嵌套类,意味着它是 Outer
类的静态成员。
1.静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static;
2.静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法;
3.静态内部类中即能声明静态成员也可以声明非静态成员。
4
问题:当我在使用i对象的test2方法时为什么系统很慢
public class Test {
public static void main(String[] args) {
Outer.Inner in =new Outer.Inner();
in.test();
Outer i =new Outer();
i.test2();
}
}
public class Outer {
private int age;
public static String Schoolname;
public static class Inner{
private String name;
public static int a;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void test(){
// System.out.println(age); 此为实例变量会报错
System.out.println(Schoolname);
System.out.println(name);//可以访问内部类中的实例变量
System.out.println(a);//可以访问内部类中的静态变量
}
}
public static void test2()
{
System.out.println(Schoolname);
// System.out.println(age);//此为实例变量不能调用
}
}
想这样强行在静态内部类中访问是报错的
三、局部内部类
(编写在方法的内部的类称之为局部内部类,也可以称为方法内部类)
局部内部类的特点
1.局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内;
2.局部内部类不可使用权限修饰符 静态(static)修饰符进行修饰 同局部变量相同;
3.局部内部类可以直接访问方法中的属性;
4.局部内部类 可以直接访问方法外部类中属性和方法;
5.局部内部类 创建对象 要在方法内部 局部内部类的外部声明
在下面代码中classA的声明有问题
在一个方法内部定义了一个局部内部类,并且这个内部类的修饰符是 public
。Java 不允许在方法内部直接定义 public
、protected
、private
或 static
修饰符的局部内部类。合法的修饰符只能是 abstract
或 final
。
public class Test {
public static void main(String[] args) {
}
public static void go()
{
public class A{
}
}
}
public class Partial {
String name = "外部类的类名";
String type = "外部类的type属性";
private int item = 1;
public static void show() {
System.out.println("掉用外部类中的show方法");
}
public void print() {
System.out.println("调用外部类中的打印方法");
}
public void demo(){
String name = "外部类方法deme()内部的方法名";
String type = "外部类方法deme()内部的type属性";
/*编写在方法的内部的类称之为局部内部类
局部内部类不可使用权限修饰符 静态修饰符进行修饰 同局部变量相同
局部内部类与局部变量使用范围一样 在此方法内部
局部内部类可以直接访问方法中的属性 重名时使用参数传递完成访问*/
class Inner{
//局部内部类 可以访问方法外部类中属性和方法
String name = "局部类的类名";
public void showInner(String name){
show();
print();
System.out.println("我是:"+ type);
System.out.println("我是:"+ Partial.this.type);
System.out.println(item);
System.out.println("我是:" + this.name);
System.out.println("我是:" + name);
System.out.println("我是:" + Partial.this.name);
}
}
//局部内部类 创建对象 要在方法内部 局部内部类的外部声明
Inner inner = new Inner();
inner.showInner(name);
}
public static void main(String[] args) {
Partial partial = new Partial();
partial.demo();
}
}
四,匿名内部类
(注意:匿名内部类只是没有类名,其他的都是具备的)
匿名内部类特点
匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
匿名内部类特点:
1. 匿名内部类就是一种特殊的局部内部类,只不过没有名称而已,基本特点和局部内部类一致
2. 匿名内部类不能有构造器,匿名内部类没有类名,肯定无法声明构造器
3. 匿名内部类的前提是,这个内部类必须要继承自一个父类或者父接口
4. 匿名内部类是接口的一种常见简化写法,也是我们开发中最常使用的一种内部类。它的本质是一个实现类父类或者父类接口具体方法的一个匿名对象。
匿名内部类不是主动去使用,而是用户需求才去使用的
public class Test {
public static void main(String[] args) {
// Animail a =new Cat();
// a.cry();
Animail a = new Animail(){
@Override
public void cry() {
System.out.println("猫喵喵的叫");
}
};
a.cry();
}
}
// class Cat extends Animail{
//
// @Override
// public void cry() {
// System.out.println("猫喵喵叫");
// }
// }
abstract class Animail{
public abstract void cry();
}
public class Test2 {
public static void main(String[] args) {
// Swimming s1 = new Swimming(){
// @Override
// public void swim() {
// System.out.println("狗要游泳");
// }
// };
// go(s1);
//简化代码,把匿名内部类传给go方法
go(new Swimming(){
@Override
public void swim() {
System.out.println("狗要游泳");
}
});
}
public static void go(Swimming s){
System.out.println("开始————————————");
s.swim();
}
}
//猫和狗都要参加游泳比赛
interface Swimming{
void swim();
}
案例
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test {
public static void main(String[] args) {
//拓展,搞清楚匿名内部类在开发中的真实使用场景
//GUI编程
//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,"登录一下");
// }
// });
//最终的核心目的是简化代码
btn.addActionListener(e -> JOptionPane.showMessageDialog(win,"登录一下"));
win.setSize(400,400);
win.setLocationRelativeTo(null);
win.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
win.setVisible(true);
}
}