Java内部类剖析

内部类

定义:定义在A类里面的B类就是内部类,B类在A类中的地位与其他成员相同,可相互调用。

内部类的使用时机

  • 在一个类中又需要定义一个等价的实体类的时候就需要定义一个内部类
  • 例如,定义一个人的实体类,同时,人又有身体上的各个自成整体的器官类,这样就需要定义一个在人这个类中的实体类。
  • 相同的一个大型的机器这个类,在其中又会有很多自成整体的零件类,可以将这些类定义在机器这个类之中。
  • 这样做的好处是:通过内部类可以让java间接的实现多继承。
  1. 实例:
	class A1 {
		
	}
	
	class B1 {
		
	}
	
	class X extends A1 {
		class Y extends B1 {
			//Y继承了B1,同时Y又是X的内部类,这样间接实现了X对A1和B1的同时继承。
		}
	}

成员内部类:

  • 定义:定义在类的内部,非static修饰的类就是成员内部类。
  • 用法:可以访问内部类所在的外部类的所有的变量和方法,不论是什么修饰符修饰的都可以访问,如果想要访问这个内部类就必须创建一个外部类的实体,然后间接的访问这个内部类。
    • 实例代码:
	class Outer{//这是外部类
		int age = 10;
		class Inner {//这是内部类
			int height = 20;
			public void play() {
				System.out.println("Inner-play" + age);
			}
		}
		
		public void show() {
			System.out.println("Outer-show");
			Inner inner = new Inner();//在类中声明一个自己的内部类的实体
			inner.play();
		}
	}

	public class Demo3 {
		public static void main(String[] args) {
			Outer outer = new Outer();
			//方法一:
			//先获取内部类对象再调用方法。
			//创建内部类的对象。
			//Outer.Inner 获取内部类的方式。
			/*
			 * Inner inner = outer.new Inner();
			 * 一般不这样写
			 */
			Outer.Inner inner = outer.new Inner();
			System.out.println(inner.height);
			inner.play();
			
			//方法二:借助于外部类的方法实现内部类方法的调用。
			outer.show();
		}
	}

局部内部类:

  • 定义:定义在一个类的方法中的类
  • 用法:将内类定义在一个内的成员方法中,将部分功能私有化。
  • 作用范围:从定义它开始到所在的方法结束。
  • 作用:对于当前的方法来说,相当于将它一部分功能面向了对象,形成了局部内部类,既保证了代码的私有化,有对代码进行了整理,增强了可读性、操作性、简化代码,增加了复用性。
  • 优点:通过局部内部类实现了功能的私有化,并对方法的内部的代码进行了整理,增强了代码的可读性。
  • 局部内部类所在的方法中局部变量的使用:
    • 局部变量的作用域:定义变量开始到函数结束。
    • final:被final修饰的变量会被放在常量区,而常量区的值存在的时间要大于局部变量所在的方法,相当于从原来的基础上扩大了作用域。
    • 原理:当方法中同时存在局部内部类与成员变量时,成员变量的使用范围就会从原来的基础上进行扩大.
    • 原因:在当前的情况下,程序会默认让final去修饰height.所以当局部变量所在的方法结束的时候,变量没有被释放,保存的值还在.
    • 关于final:
      1. 变量必须与局部内部类同时存在.
      2. 在jdk1.7之前要想保住局部变量的值,要手动添加final。
      3. 在jdk1.7之后,java的内部机制已经在变量的前面默认添加了final。
  • 实例代码:
	class Outer1{
		int age = 10;
		public void show() {
			System.out.println("Outer-show");
			class Inner {//局部内部类
				int height = 20;
				public void play() {
					System.out.println("Inner-play" + age);
				}
			}
			Inner inner = new Inner();
			inner.play();
		}
	}
	
	class Test {
		public void play() {
			class GongNeng{
				public void gongneng01() {
					System.out.println("功能1");
				}
				public void gongneng02() {
					System.out.println("功能2");
				}
			}
			GongNeng gongNeng = new GongNeng();
			gongNeng.gongneng01();
			gongNeng.gongneng02();
		}
		public void run() {
			//因为两方法是play的局部内部类方法。play内部能够使用,外部不行。
	//		gongneng01();
	//		gongneng02();
		}
	}

匿名内部类(对象):

  • 定义:定义在一个类方法中的匿名子类对象,属于局部内部类
  • 解释:匿名内部类是没有构造器的(唯一一个没有构造器器的类),所以他的使用范围非常狭窄,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
  • 作用:
    • 当只用到当前子类的一个实例对象的时候,定义好马上使用。
    • 当不好起名字的时候,可以使用。
    • 可以更好的定义运行时的回调,做服务器的时候可以用到。
  • 注意点:
    • 匿名内部类对象必须有父类或者父接口。类似于多态的效果。
-匿名对象和匿名子类对象:
  • 具体实现方法在如下的代码
	// 研究匿名对象,匿名子类对象
	class Test1 {
		public void test1Method() {
			System.out.println("test1.Method");
		}
	}
	
	class SubTest1 extends Test1 {
		@Override
		public void test1Method() {
			// TODO Auto-generated method stub
			System.out.println("SubTest1-Method");
		}
	}

	public class Demo6 {
		public static void main(String[] args) {
			// 创建匿名对象,完成方法调用
			new Test1().test1Method();
	
			// 创建匿名子类对象
			/*
			 * 第一种方法:使用已有的子类生成匿名子类对象并调用方法 
			 * 应用场景:现成的子类可以使用多次,相同的功能要调用多次的时候。
			 */
			new SubTest1().test1Method();
	
			/*
			 * 第二种方法:直接创建没有名字的Test1类的匿名子类对象 
			 * 构成:new + 父类的名字/父接口名字 + (){匿名子类的执行体}+“;”
			 * 应用场景:只能使用一次,使用完了立即释放,每次都是不同的功能。
			 */
			new Test1() {
				@Override // 重写的test1Method方法
				public void test1Method() {
					System.out.println("匿名的子类方法");
				}
				//子类特有的方法
				public void bark(){
					System.out.println("bark");
				}
			}.bark();
			// 给匿名对象起一个名字
			SubTest1 subTest1 = new SubTest1();
			Test1 test1 = new Test1() {// 多态的方式取名字。
				@Override // 重写的test1Method方法
				public void test1Method() {
					System.out.println("匿名的子类方法");
				}
				//子类特有的方法
				public void bark(){
					System.out.println("bark");
				}
			};
		}
	}
匿名内部类:
  1. 说明:可以做匿名的参数、可以做为一个函数的参数(匿名对象做参数、匿名内部类做参数)、可以做为返回值(普通的匿名对象做返回值、匿名对象做返回值)。具体实现过程见如下代码。
    • 实例代码:
	class Test1 {
		public void test1Method() {
			System.out.println("test1.Method");
		}
	}
	class Out {
		public void show() {
			new Test1() {
				@Override//重写的test1Method方法
				public void test1Method() {
					System.out.println("匿名的内部类子类方法");
				}	
			}.test1Method();
			new Test1() {//这是两个相同的。
				@Override//重写的test1Method方法
				public void test1Method() {
					System.out.println("匿名的内部类子类方法");
				}	
			}.test1Method();
		}
		
		//普通的匿名对象作为参数
		public void testCanshu1() {
			System.out.println(new Test1());
		}
		
		//匿名内部类做参数
		public void testCanshu2() {
			System.out.println(new Test1(){
				public void bark() {
					System.out.println("bark");
				}
				@Override
				public String toString() {
					// TODO Auto-generated method stub
					return super.toString();
				}
			});
		}
	
		//普通的匿名对象充当返回值
		public Test1 testFanhuizhi1() {
			return new Test1();
		}
		
		//匿名内部类充当返回值
		public Test1 testFanhuizhi2() {
			return new Test1(){
				public void bark() {
					System.out.println("bark");
				}
				@Override
				public String toString() {
					// TODO Auto-generated method stub
					return super.toString();
				}
			};
		}
	}

	public class Demo6 {
		public static void main(String[] args) {
			//研究匿名内部类--测试
			Out out = new Out();
			out.show();
			out.testCanshu1();
			out.testCanshu2();
			Test1 test1 =  out.testFanhuizhi1();
			test1.test1Method();
			Test1 test12 = out.testFanhuizhi2();
		}
	}

静态的内部类
  • 解释:
    • 静态的内部类中可以没有静态的成员。
    • 有静态成员的一定是静态的内部类
    • 实例代码:
	public class Demo7 {
		public static void main(String[] args) {
			//静态的对象
			//要保证内部类本身是静态的
			//构成:new  外部类.内部类+()
			Out1.In1 in1 = new Out1.In1();
			//调用非静态方法
			in1.play();
			//调用静态的方法
			in1.song();
			Out1.In1.song();
		}
	}
	
	class Out1{
		 static  class In1{//静态的内部类
			 //非静态的方法
			public void play() {
				System.out.println("play");
			}
			 //静态的方法
			public static void song() {
				System.out.println("song");
			}
		}
	}

总结

内部类的作用:
1. 间接实现了多继承。
2. 方便定义。
3. 只有外部类可以访问创建的内部类的属性和方法,包括私有方法。
4. 同一个包中其他的类不可见,有了很好的封装性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值