内部类

文章目录

    • 什么是内部类
    • 成员内部类
    • 局部内部类
    • 静态内部类
    • 匿名内部类

什么是内部类

顾名思义,定义在一个类内部的类就是内部类。为了便于区分,这个内部类所在的类就被称为外部类。
内部类是为了方便开发而设计的,有些类是专门为了另一个类开发的,所以干脆直接将这些类写到对应的类的内部。
根据内部类的位置、修饰符和定义方式不同,一共有四种内部类:

  • 成员内部类
  • 局部内部类
  • 静态内部类
  • 匿名内部类

成员内部类

在一个类中定义的内部类,就像属性和方法那样,就是成员内部类。在成员内部类中可以访问外部类的所有属性和方法,外部类中也可以访问成员内部类的属性和方法。
让我们来看个例子:

//外部类Out
class Out{
	//外部类的属性
	String s="外部类属性";
	//外部类方法
	void outMethod() {
		System.out.println("外部类的方法outMethod");
	}
	//在外部类访问内部类的属性和方法
	void visitIn() {
		In in=new In();
		System.out.println("内部类的属性s:"+in.s);
		in.inMethod();
	}
	
	//内部类
	class In{
		//内部类的属性
		String s="内部类属性";
		//内部类方法
		void inMethod(){
			System.out.println("内部类的方法inMethod");
		}
		//在内部类中访问外部类的属性和方法
		void visitOut() {
			System.out.println("外部类的属性s:"+s);
			outMethod();
		}
	}
}
//测试
public class InnerClassDemo01 {
	public static void main(String[] args) {
		//生成外部类对象
		Out o=new Out();
		//生成内部类对象,必须通过外部类对象调用new操作符来生成内部类对象
		Out.In i=o.new In();
		//在外部类中访问内部类成员
		System.out.println("在外部类中访问内部类成员");
		o.visitIn();
		//在内部类中访问外部类成员
		System.out.println("在内部类中访问外部类成员");
		i.visitOut();
	}
}

生成内部类对象时,语法格式是:外部类.内部类 对象名=外部类对象.new 内部类构造方法;

局部内部类

它定义在方法中,可以访问外部类的属性和方法,但局部内部类的属性和方法只能在所在的方法中被访问,而不能被外部类访问。
我们来看例子:

//包含方法内部类的外部类
class Out{
	//包含方法内部类的方法
	void inMethod() {
		String so="方法中的对象";
		class In{
			//内部类中的属性
			String si="方法内部类中的字符串";
			//内部类中的方法
			void inMethod() {
				System.out.println("内部类的属性:"+si);
				System.out.println("外部类的属性:"+so);
				//访问外部类的方法
				m1();
			}
		}
		In in=new In();
		in.inMethod();
	}
	//外部类方法
	void m1() {
		System.out.println("这里是外部类的方法");
	}
}
//测试
public class InnerClassDemo02 {
	public static void main(String[] args) {
		Out out=new Out();
		out.inMethod();
	}
}

静态内部类

static关键字修饰的成员内部类就是静态内部类,静态内部类只能访问外部类的静态成员,而且外部类访问静态内部类时,可以直接访问,就像访问静态方法和静态属性那样:外部类.静态内部类 对象名=new 外部类.静态内部类构造方法;
我们来看一个例子:

//包含静态内部类的外部类
class Out{
	static String s="外部类的静态属性";
	static class In{
		//静态内部类的方法
		void inMethod() {
			System.out.println("外部类的静态属性:"+s);
		}
	}
}
//测试
public class InnerClassDemo03 {
	public static void main(String[] args) {
		//生成内部类对象
		Out.In in=new Out.In();
		in.inMethod();
	}
}

匿名内部类

如果有一个方法的参数是一个接口的对象,怎么办?按照之前学过的方法,当然是设计一个实现这个接口的类,让这个类的对象成为方法的参数。
但这么写比较繁琐,为了简化这类问题,我们可以使用匿名内部类。使用匿名内部类时,可以将对接口的实现直接写到方法的参数部分:

方法名(new 接口(){
    接口的实现代码;
})

由于这个过程中实现了接口,但并没有给实现接口的类起名字,所以叫做匿名内部类。
为了方便理解,我们直接看例子:

//接口
interface Meet{
	void sayHello();
	void sayGoodbye();
}
public class InnerClassDemo04 {
	//以Meet接口对象为参数的方法
	public static void say(Meet m) {
		m.sayHello();
		m.sayGoodbye();
	}
	public static void main(String[] args) {
		//调用say方法
		say(new Meet() {		
			@Override
			public void sayHello() {
				System.out.println("Hello!");
			}
			@Override
			public void sayGoodbye() {
				System.out.println("Goodbye!");	
			}
		});
	}
}

在四种内部类中,用的最多的就是匿名内部类,例如在Java图形界面设计中,大量使用匿名内部类来实现各种监听器。具体内容我们在后面的文章中会进行说明。

04

你可能感兴趣的:(Java11学习,Java,内部类)