Java内部类的概念

来源:互联网 发布:电子秤数据倒显 编辑:程序博客网 时间:2024/05/22 12:43
// 外部类只能处于public和默认访问级别,而成员内部类可以处于public,protected,private和默认这四种访问级别,
// 访问内部类的格式 Outer.InnerTool tool = new Outer().new InnerTool();而在外部类中可以直接使用InnerTool,private InnerTool tool = new InnerTool();
// 成员内部类还可分为两种,实例内部类和静态内部类,后者用static修饰,不管何种都应该保证内部类和外部类不重名
// 实例内部类的特定:在创建实例内部类时,外部类的实例必须已经存在,例如要创建InnerTool类的实例,必须创建Outer外部类的实例,在内部类中可以直接访问外部类的所有成员,包括成员变量和成员方法
// 外部类中不能直接访问内部类的成员,必须通过内部类的实例去访问,在实例内部类中不能定义静态成员,而只能定义实例成员,如果实例内部类B与外部类A包含同名的成员(比如成员变量v),那么在类B中,this.v表示类B的成员
// A.this.v表示类A的成员。
// 静态内部类的特点:在创建内部类的实例时,不必创建外部类的实例,例如:A.B b = new A.B();,静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,就必须通过外部类的实例去访问,
// 在静态内部类中可以定义静态成员和实例成员,客户类可以通过完整的类名直接访问静态内部类的静态成员,但不能直接访问静态内部类的实例变量,
// 局部内部类的特点:在方法中定义的内部类,可见范围是当前方法,和局部变量一样,局部内部类不能用public,private,protected及static修饰符来修饰,局部内部类只能在方法中使用,不能包含静态成员
// 在局部内部类中定义的内部类也不能被public,protected,private这些访问控制符修饰,局部内部类也可以访问外部类的所有成员,局部内部类还可以访问所在方法中的final类型的参数和变量
// 内部类的继承:当外部类Sample继承了另一个外部类Outer的内部类Inner,那么每个Sample实例必须自动引用一个Outer实例,当调用一个Sample实例的print(),
// print()方法会访问当前Outer实例的成员变量a,public class Sample extends Outer.Inner{},public Sample(Outer o){o.super();},这个构造方法表示java编译器会要求Sample类的构造方法必须
// 通过参数传递一个Outer实例的引用,然后在构造方法中调用super语句来建立Sample实例与Outer实例的关联关系,
// 子类与父类中的内部类同名:内部类不存在覆盖的概念,因为具有不同的命名空间,
// 匿名内部类的特点:这种类没有名字,new A(){}表示定义类一个继承类A的匿名类,大括号内是类A的类体,匿名类本身没有构造方法,但是会调用父类的构造方法,new A(v){},如果v是局部变量,并且在匿名类的类体中会使用它,那么v必须是final类型
// 匿名类虽然没有构造方法,但是可以在匿名类中提供一段实例初始化代码,java虚拟机会在调用父类的构造方法后执行这段代码,除了可以在外部类的方法内定义匿名内部类以外,还可以在声明一个成员变量时定义匿名类,匿名类除了可以继承类以外,还可以实现接口
// 匿名类和局部内部类一样,可以访问外部类的所有成员,如果匿名类位于一个方法中,还能访问所在方法的final类型的变量和参数。局部内部类和匿名类一样在方法外是不可见的。
// 局部内部类可以多次创建局部内部类的实例,而匿名类只能创建一次实例。
// 内部接口及接口中的内部类,外部类中可以包含一个静态内部接口,public class Outer{public static interface Tool{public int add(int a,int b)}},接口中也可以定义内部类
// 内部类的用途:封装类型,直接访问外部类的成员,回调外部类的方法,
// 封装类型:如果一个内部类仅仅为特定的方法提供服务,那么可以把这个内部类定义在方法内,
// 直接访问外部类的成员,例如类A和类B,如果使类B能够访问类A的count属性,此时类A必须提供getCount()和setCount()方法,此外,还要建立类B到类A的关联关系
// 如果此时类A的count属性不允许除了类B以外的其他类读取或设置,那么以上实现方式就不能满足,这种情况下,把类B定义为内部类就可以解决这个问题,内部类B可以直接访问类A的属性count了

// 回调:当一个接口和一个抽象类中包含同样方法名的方法,此时你可以只继承抽象类,再写一个实例内部类实现那个接口,也就同时包含了抽象类和接口中的两个同名方法,接着创建getCallBackReference方法,new一个内部类,返回一个内部类的实例,此时调用者获取到这个实例就可以调用内部类中的那个方法了

interface Adjustable{public void adjust(int temperature);}class Base1{private int speed;public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}public void adjust(int speed){this.speed = speed;}}// 接口Adjustable和类Base1中都有一个adjust方法,所以只能继承一个Base1,另一个则通过 实例内部类来实现他的adjust方法// 接着通过一个public方法来返回实现这个接口的实例,通过实例再回调他的adjust方法// 回调指的是一个类尽管实际上实现了某种功能,但是没有提供相应的接口,此时可以通过这个类的的内部类的接口来获得这种功能,这个内部类本身并没有提供真正的实现,仅仅调用外部类的实现,// 由此可见回调充分发挥了内部类所具有的访问外部类的实现细节的优势。public class Test8 extends Base1{public int getTemperature() {return temperature;}public void setTemperature(int temperature) {this.temperature = temperature;}private int temperature;private void adjustTemperature(int temperature) {this.temperature = temperature;}private class Closure implements Adjustable{@Overridepublic void adjust(int temperature) {adjustTemperature(temperature);}}public Adjustable getCallBackReference(){return new Closure();}}


0 0