java面向对象24 内部类(InnerClass)的使用

/*

  • 类成员结构之内部类的使用
  • 1,Java中可以在一个类A中定义一个类B,类A为外部类,类B为内部类,
  • 注意内部类B的类名不能与外部类A重名
  • 成员内部类编译以后生成 外部类名$内部类名.class字节码文件
  • 局部内部类编译以后生成 外部类名$ 数字 内部类名.class字节码文件(加数字为了防止重名)
  • 2,内部类按照声明的位置分为:
  • 成员内部类(静态的与非静态的)
  • 1,作为外部类的成员
  • 可以调用外部类的结构

  • 不同于外部类不能被static修饰,内部类可以声明为static的。

  • 不同于外部类只能用public或缺省权限,内部类可以使用private和protected修饰

  • 2,作为一个类
  • 类内可以有属性,方法,构造器,代码块,内部类

  • 类可以被继承,也可以用final修饰,声明不能被继承

  • 内部类可以是抽象类,可以被abstract修饰

  • 3,成员内部类的使用:
  • 3.1创建成员内部类的变量
  • 静态内部类对象:外部类名.内部类名 变量名 = new 外部类名.内部类名();
  • 非静态内部类对象:需要使用外部类的实例化对象调用创建 外部类名.内部类名 变量名 = 外部实例对象名.new 内部类名();
  • 3.2成员内部类调用外部类结构
  • 调用同名同参方法:

  • 外部类名.this.方法名();
  • this.方法名();
  • 没有同名方法时直接使用 方法名();的方式就可以自动识别
  • 调用同名属性:

  • 外部类名.this.属性名();
  • this.属性名();
  • 没有同名方法时直接使用 属性名 的方式就可以自动识别。
  • 3.3成员内部类使用注意
  • 非static的成员内部类中的成员不能声明为static的,只有在外部类或static的成员内部类中才可声明static成员。(从成员生命周期角度考虑,需要一致)

  • 外部类访问成员内部类的成员,需要“内部类.成员”(静态内部类)或“内部类对象.成员”(非静态内部类)的方式

  • 成员内部类可以直接使用外部类的所有成员,包括私有的数据

  • 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的(内部类作为外部类的一个结构,与属性方法类似,需要是静态的才能被外部类的静态方法调用)

  • 总结:成员内部类相比外部类可以使用的权限修饰符多了两个,可以声明为静态的,限制为静态内部类不能有非静态结构。
  • 4,局部内部类(定义在构造器,方法体,代码块中,先声明后使用。除此之外的任何地方都不能使用该类)
  • 4.1局部内部类的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型
  • 4.2局部内部类可以使用外部类的成员,包括私有的。
  • 4.3局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
  • 4.4局部内部类不能使用static修饰,因此也不能包含静态成员
  • 4.5局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的生命周期不同所致。
  • 4.6局部内部类可以声明为final和abstract的
  • 总结:局部内部类很少用,限制比成员内部类多。通常用在实现一个接口上。内部只需要重写接口的抽象方法。
  • 5,匿名内部类
  • 5.1匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
  • 5.2匿名内部类必须继承父类或实现接口
  • 5.3匿名内部类只能有一个对象,对象只能使用多态形式引用
  • 5.4匿名内部类的使用格式与父类类和接口的匿名类的使用方法相同。

*/

package object_chapter2;

public class Object_InnerClass {
	static int number = 10;
	int arguments = 20;
	

	public static void main(String[] args) {
		//创建静态成员内部类对象
		Vehicle.Engine e = new Vehicle.Engine();
		System.out.println("发动机有" + e.cylinderNumber + "个汽缸");
		new Vehicle.Engine().work();
		//创建非静态成员内部类对象
		Vehicle v = new Vehicle();
		Vehicle.Room r = v.new Room();//或者v.new Vehicle.Room()
		System.out.println("车里有" + r.chair + "个座位");
		r.reName("车名:五菱之光");
		new Vehicle().new Room().set();	
		v.getInstance().compare(v);
		
	}
		
	public static void method() {
		
		int num = 11;
		//方法体内的局部内部类
		 class InnerClass{
			void show() {
//				num = 12;
				System.out.println(num);//局部内部类的方法中可以调用内部类所在方法的局部变量。不能修改
				//在JDK1.7及以前,局部变量想要被局部内部类调用必须显式的被声明为final类型的,JDK1.8后会自动识别为final的。
				//由于局部内部李生成的字节码文件是独立的,外部类中的变量想要被内部类使用只能是常量,内部类使用的是外部类变量的副本
				//只能使用,无法修改。
			}
			
		}
//		 num++;//final的变量不能修改,否则局部内部类调用时会报错。
	}
	
    public Object_InnerClass() {
    	//构造器中定义的局部内部类
		 class InnerClass{
			
		}		
	}
    
    {
    	//代码块中定义的局部内部类
    	 class InnerClass{
    		
    	}
    }
    
	//静态内部类
	private static final class InnerClass1{
		void method() {
		number = 110;
//		Object_InnerClass.this.arguments = 20;//静态内部类中无法调用非静态结构
	 }
	}
	
	//非静态内部类
	protected class InnerClass2{
		void method() {
			Object_InnerClass.number = 110;
			Object_InnerClass.this.arguments = 20;//非静态内部类中可以调用非静态结构
			}
	}
	
	class InternalClass{
		//内部类中也可以嵌套一个内部类
		class InnerInternalClass{			
		
	    }
	}		
}

class Vehicle{
	static int wheelNumber = 4;
	String name = "号称秋名山之神";
	
	void run() {
		System.out.println("可以在各种路况上跑");
	}
	//静态成员内部类
	static class Engine{
		int cylinderNumber = 4;
		void work() {
			System.out.println("输出200匹马力的动力");
		}
				
	}
	//非静态成员内部类
	class Room{
		//static int chair = 4;//非静态内部类不允许使用静态结构
		int chair = 7;
		String name = "内部空间极大";
		void set() {
			Vehicle.this.run();//内部类可以调取外部类的结构
			carry();//不重名的情况下可以省略前面的部分
			System.out.println("可以坐很多个人");
		}
		
		void reName(String name) {
			System.out.println(name);//调用方法形参
			System.out.println(this.name);//调用内部类属性
			System.out.println(Vehicle.this.name);//调用外部类同名属性
		}
	}
	
	   void carry() {
		System.out.println("能拉人能载货");
		
	}
	//局部内部类的常见场景,方法返回值是一个接口或者抽象类
	 Comparable getInstance() {
		 //创建一个内部类为借口的实现类
		class MyCompareable implements Comparable{

			@Override
			public void compare(Vehicle v) {
				System.out.println("不管什么车都挡不住五菱的光辉!!");				
			}
			
		}
		//返回内部类的实例
//		return new MyCompareable();	
		//方式二,使用匿名内部类
		return new Comparable() {
			
			@Override
			public void compare(Vehicle v) {
				System.out.println("天下无敌");				
			}
		};						
	}				 
}

interface Comparable{
	 void compare(Vehicle v);
}
发布了47 篇原创文章 · 获赞 1 · 访问量 1045

猜你喜欢

转载自blog.csdn.net/wisdomcodeinside/article/details/104455753