可以将一个类的定义放在另一个类的定义的内部,这就是内部类。
起初看内部类只是一种名字隐藏和组织代码的模式。当生成内部类对象时,此对象与制造它的外围对象之间有一种联系,它可以访问外围对象的所有成员。此外内部类还有外围类所有元素的访问权限。使用它的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的、可以继承多个具体的或者抽象的类的能力,一些设计与编程的问题就很难解决。例如,如果拥有的是抽象类或者具体的累而不是接口,那就只能使用内部类来实现多重继承。
内部类自动拥有对其外围类所有成员的访问权,这是如何做到的?当某个外围类对象创建了一个内部类对象时,此内部类对象必定会秘密的捕获一个外围类对象的引用, 然后在你访问此外围类成员的时候,就会那个引用选择外围类的成员。幸运的是编译器会帮你处理所有细节(内部类对象只能在与其外围类对象相关的情况下,即内部类是非static时),如果你创建的是嵌套类(静态内部类)就不需要对外部类对象的引用。
生成外部类对象的引用可以用外部类的名字+“圆点”+“this”(外部类名字.this),这样生成的引用自动具有正确的类型,而且因为编译期就验证过,所以运行时没有任何运行开销。
创建内部类对象,必须使用外部类对象创建内部类对象。
内部类向上转型:当内部类向上转型为其基类尤其是转型为一个接口时(从实现了某个接口的对象,得到对其接口的引用,与向上转型为这个对象的基类,实质是效果是一样的。),因为,内部类--------某个接口的实现---------能够完全不可见,并且不可饮用。所得到的只是指向某个基类或者接口的引用,所以能够很方便的隐藏实现细节。
在任意的方法或作用域内实现内部类,这么做的原因:1)你实现了某类型的接口,于是创建并返回对其的引用。2)解决一个复杂的问题,需要一个来辅助你的解决方案,但是又不希望这个类是公共可用的。
eg:匿名内部类
public class Parcel{
public Contents contents(){
return new Contents(){
private int i = 1;
public int value(){return i;}
}
}
public static void main(String[] args){
Pracel p = new Pracel();
Contents c = p.contents();
}
}
eg:接口内部类
public interface ClassInterface{
void howdy();
class Test implements ClassInterface{
public void howdy(){
System.out.println("Howdy!!!!!");
}
public static void main(String[] args){
new Test().howdy();
}
}
}
eg:在接口中写一些公共代码来实现某些想法比如测试,那么接口中写嵌套类会很方便
public class Test{
public void f(){System.out.println("f()");}
public static void main(String[] args){
Test test = new Test();
test.f();
}
}
内部类包括:局部内部类(在任意作用域内)、匿名内部类(看起来似乎是正在创建一个Contents对象,但是在到达语句结束的分号之前你却说:“等等,我想在这里插入一个类的定义。”)、嵌套类(静态内部类,不能访问非静态的外围类对象,创建时不需要外围类对象,普通内部类不能有static数据和字段,也不能包含嵌套类,但嵌套类可以包含所有这些东西)、接口内部类(正常情况下接口内部不能放置任何对象,但嵌套类可以作为接口的一部分)/
匿名内部类中不可能有命名构造器,因为它根本没有名字!!!!但通过实例初始化,就能够达到为匿名内部类创建构造器的效果。因为匿名内部类既可以扩展类也可以实现接口,但两者不能兼备。而且如果实现接口,也只能实现一个接口。内部类还有一些其他的特性:1)内部类可以有多个实例,每个市里都有自己的状态信息,并且与外围类对象的信息相互独立。2)在单个外围类中,可以让多个内部类以不同的方式实现同一个接口或者继承同一个类。3)创建内部类的时刻并不依赖于外围类对象的创建 4)内部类并没有令人迷惑的“is--a”关系;他就是一个独立的实体。
内部类的闭包:闭包是一个可调用的对象,记录了包含外围类对象的信息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有的成员,包括private成员。闭包的功能比指针更加安全灵活。
内部类与控制框架:
程序框架就是设计用以解决某类特定的问题的一个类或一组类。控制框架就是一类特殊的应用程序框架,它用来解决相应事件的需求。主要用来响应事件的系统叫做时间驱动系统。应用程序中常见的问题之一就是图形用户接口(GUI),他几乎完全是事件驱动系统,