嵌套类——java

目录

一、嵌套类基础

二、静态嵌套类:

三、普通内部类:

四、局部内部类

五、匿名内部类:

六、嵌套类对比:

七、嵌套类的应用场景


一、嵌套类基础

嵌套类:一个类定义在别的类得内部。

如:

//文件名B.java
//A类在B类中定义,嵌套
public class B {
	class A	{
		
	}
}

静态嵌套类:即类前有static修饰符

扫描二维码关注公众号,回复: 11067962 查看本文章

非静态嵌套类:又名内部类。可分普通内部类,局部内部类,匿名内部类。

优点:

  • 不同得访问权限要求,更细粒度得访问控制
  • 简洁,避免过多得类定义

缺点:

  • 语言设计更加复杂,较难掌握和使用

二、静态嵌套类:

注意区分于静态类:只有静态方法和属性,并且用static修饰。

静态嵌套类:

  • 层级和包围类的成员变量/方法一样
  • 第三方需要外部包围类才可以访问静态嵌套类格式:外部包围类名.静态嵌套类名
  • 需要static修饰
  • 可以定义静态成员和非静态成员
  • 不能访问包围类的非静态变量,客以访问包围类的静态成员,可以通过包围类的对象进行访问非静态成员
  • 外界可以通过静态嵌套类名访问静态成员,通过对象访问其非静态成员
  • 外界需要通过包围类才可以访问到静态嵌套类,并创建其对象,不需要外部包围类的实例
public class Outer1 {
	String name;

	// 静态嵌套类
	static class Inner1 {
		String name;
	}
}

三、普通内部类:

普通内部类:

  • 非static类,定义外某个类的成员变量的位置
  • 定义后,在类里面都可以使用
  • 编译后名称为:外部类名+$+内部类名
  • 可以继承其他的继承或者实现其他的接口
  • 可以用private/default(不写)/protected/public控制外界控制
  • 非静态类,不能实现静态变量/方法,常量除外
  • 和外部包围类的实例相关,一个普通内部类实例肯定是在一个外部包围类始终中,且可以访问外部包围类的所有成员
  • 在第三方类中,需要先创建外部包围类实例,才能创建普通内部类实例,不允许单独的普通内部类存在
public class Outer2 {
	String name;
	
	//普通内部类/成员内部类
	public class Inner2	{
		String name;
	}
}

 举例:

public abstract class Animal {
	public abstract void eat();
}
public interface Flyable {
	public void fly();
}
public class Outer3 {
	String name = "aaaaaa";
	
	public class Bird extends Animal implements Flyable {
		public static final int a=3; //常量OK
		//public static int b = 4;   //error
		public void fly() {
			System.out.println("I can fly " + name);
		}

		public void eat() {
			System.out.println("I can fly");
		}
	}
	public Bird obj = new Bird();
	public void f1() {
		obj.fly();
		System.out.println(obj.getClass().getName());
		this.name = "bbbbbb";
		obj.fly();
	}
	
	public Bird getBird()
	{
		return this.obj;
	}
}
public class Outer3Test {

	public static void main(String[] args) {
		Outer3 foo1 = new Outer3();
		foo1.f1();
		
		Outer3.Bird foo2 = foo1.new Bird();
		foo2.fly();
		System.out.println(foo2 == foo1.getBird());
		
		//foo1对象下,有2个内部类对象和它关联
		
		//不允许没有关联的单独的普通内部类对象,会报错
		//Outer3.Bird foo3 = foo1.new Outer3.Bird();
	}

}

四、局部内部类

局部内部类:

  • 定义在代码块中的非静态类,如方法,for循环,if语句等
  • 定义后创建对象即可使用
  • 只能活在定义的这个代码块中,代码块结束后,外界将无法使用该类。
  • 编译后名称为:外部类名+$+序号+内部类名
  • 可以继承其他类,或者实现其他接口
  • 非静态类,不能实现静态变量/方法,常量除外
  • 可以访问外部包围类成员变量,访问格式:包围类名.this.变量名
  • 如果定义在静态方法中,则只能访问包围类的静态成员
  • 不能是一个接口,即接口不能定义在代码中。
public class Outer3 {
	String name;
	
	//局部内部类
	public void f1() {
		class Inner3	{
			String name;
		}
	}	
}

五、匿名内部类:

匿名内部类:

  • 没有类名得内部类,必须继承一个父类/继承一个父接口;
  • 在实例化之后,迅速转型为父类/父接口;
  • 这种类型得对象,只能new一个对象,之后以对象名字操作;
  • 可以在普通语句和成员变量赋值时使用内部类。
  • 可以继承、改写,补充父类、父接口的方法;
  • 没有正式的类名,编译器产生的内部名字为:类名+$+数字变号。

注意:

  • 匿名内部类不可以含静态变量和方法(常量除外);
  • 访问外围变量需要以格式:“类名.this.变量名”来访问;
  • 若匿名内部类定义在静态方法内,只能访问外围得的静态变量;
  • 不可以重用,即使两个相同匿名内部类的语句实例化出来的类和对象都不一样。

示例:

Runable()是接口,不可以new,所以new了之后加了run()方法,类定义后无名字称为匿名内部类。

一般使用在只使用一次得场合中。

public class Outer4 {

	String name;
	
	//匿名内部类
	public void f1() {
		new Thread(new Runnable() {
			public void run()
			{
				System.out.println("hello");
			}
		}).start();
	}
}

六、嵌套类对比:

静态嵌套类:在一个类中定义,可重复使用,并需要访问外部类的静态成员。

普通内部类:和局部内部类类似,在一个类中定义,可重复使用,可以访问外部类的成员,但不需要访问外部类方法的形参和内部变量。

局部内部类:在一个方法内,需要创建一个新的类型,并且重复使用

匿名内部类:如果需要定义额外的变量和方法

七、嵌套类的应用场景

匿名内部类:android开发中常用匿名内部类实现监听。

普通内部类:广泛使用在具有母子结构的类总,内部类对象和外围对象保持紧密联系。

局部内部类:继承某一个类或接口,重新定义方法,并当作返回值在外部使用。

静态嵌套类:感觉和普通类一致,和外围类没有太多的联系,可以脱离外围对象存在,也可以访问外围类的静态成员。普通内部类可以访问外部所有的成员。所以一般用普通内部类就可以了,如果不需要访问外围类的非静态成员,则使用静态嵌套类,因为可以节省普通内部类和外围类的联系开销。

参考中国大学mooc《java核心技术》

发布了55 篇原创文章 · 获赞 17 · 访问量 4989

猜你喜欢

转载自blog.csdn.net/weixin_43698704/article/details/104226632