回顾《JAVA编程思想》第四版 第十章 内部类特点和实现JAVA“多重继承”

1 篇文章 0 订阅

什么是内部类,匿名类,匿名接口,匿名方法?

内部类有什么特点?

内部类有哪些应用?

JAVA语言是一个JAVA文件名对应一个类名称,在类作用域里面所定义的类就是内部类,它可以是静态,或是非静态的。而我们关注的大部分是非静态内部类。为什么要定义内部类呢?

从面向对象来讲,比如人有心脏,人被定义成类后,心脏是其身体必要的一部分,在设计时,我们可以把心脏定义成外部类,但是设计成内部类不是更加符合现实意义吗?是的。

对于现实世界中的场景抽象,很多都需要内部类的支持。当然这不仅仅是SUN公司设计出内部类的唯一用处,内部类最大的特点就是其不是单一存在,其还有一个外部对象的引用,在内部类中可以任意操作外部对象的属性和方法,包括private。我引用了《Think in Java》中的代码。

 

package thinkInJava;

public class Outer {

	private int o_a = 10;

	public void print() {
		System.out.println(o_a);
	}

	public Inner newInner() {
		return new Inner();
	}

	class Inner {
		private int i_b = 5;
		public Outer getOuter() {
			return Outer.this;
		}
		public void showstop() {
			System.out.println(o_a);
		}
	}

	public static void main(String args[]) {
		Outer outer = new Outer();
		Inner inner = outer.newInner();
		inner.getOuter().print();
		inner.showstop();
	}
}

所以说脱离了外部对象,内部对象是不可能存在的(静态内部类除外)。同样代码附上。

 

package thinkInJava;

public class Outer {

	private int o_a = 10;

	public void print() {
		System.out.println(o_a);
	}

	public Inner newInner() {
		return new Inner();
	}

	static class Inner {
		private int i_b = 5;
		public void print(){
			System.out.println(i_b);
		}
		public void haveATry() {
			i_b++;
		}
	}

	public static void main(String args[]) {
		Outer outer = new Outer();
		Inner inner = outer.newInner();
		inner.print();
		inner.haveATry();
		Outer.Inner inner1 = new Inner();
		inner1.print();
		Outer outer1 = new Outer();
		Inner inner2 = outer1.newInner();
		inner2.print();
	}
}

 

这里有一点,是Inner没办法用.this来获取外部类实例,

有一些注意点,一是非内部类中是不允许有内部变量、方法或类,即不允许定义静态内部成员

因为静态变量的作用就是让所有类对象共享一个状态,而这和内部类要依赖外部类对象存在产生矛盾。

内部类可以继承类或实现接口。典型的类子可以看一看HashMap,HashTable的源码,里面定义了Entry内部类,而且此内部类实现了Map.Entry的接口。

二是我们也应该关注到SUN引入内部类的又一优点,就是变相实现了JAVA多重继承,本身一个类是没办法继承多个类的,但是可以定义多个内部类,之后对内部类的一系列操作来实现这个特点。当然,你也可以用asm来实现JAVA多重继承。

 

public class Outer {
	class InnerA extends A {
	}

	class InnerB extends B {
	}
	......
}

 

三是内部类下面还可以再定义内部类,理论上应该可以无限嵌套下去(这个没试过……)。

四是可以匿名定义类,接口。最相关的实例就是SWING中GUI的事件驱动模型,和声明各种监听器。

五是内部类/接口可以被继承/实现,但是初始化要同时关联到内部类的外部对象

 

package thinkInJava;

class WithInner{
	class Inner{}
}
public class Outer extends WithInner.Inner{
	
	public Outer(WithInner wi){
		wi.super();
	}
	
	public static void main(String args[]) {
		WithInner wi = new WithInner();
		Outer t = new Outer(wi);
	}
}

 六是内部类不可以被外部类的子类覆盖,二者是独立存在的。

package thinkInJava;

public class Outer {

	class WithInner {
		class Inner {
			public void print() {
				System.out.println("super inner class");
			}
		}

	}

	class InheritWithInner extends WithInner {
		class Inner {
			public void print() {
				System.out.println("child inner class");
			}
		}

		public Inner newInner() {
			return new InheritWithInner.Inner();
		}

		public WithInner.Inner newInner1() {
			return new WithInner.Inner();
		}
	}

	public void test() {
		InheritWithInner tt = new InheritWithInner();
		tt.newInner().print();
		tt.newInner1().print();
	}

	public static void main(String args[]) {
		Outer outer = new Outer();
		outer.test();
	}
}
 

 

对于内部类,自己还是需要大量时间去使用,去体会。适时用,用的好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值