一、继承与清理
如果某个类需要去清理自身的资源,那么必须用心为其创建回收垃圾的方法,而如果此类有导出的子类,那么必须在导出类中覆盖回收的方法,当覆盖被继承类的回收垃圾的方法的时候,需要注意销毁的顺序应该和初始化的顺序相反。对于字段来说,意味着与声明的顺序相反。应该先对导出类进行清理,然后才是基类。这是因为导出类的清理可能会调用基类的某些方法,所以需要使基类的构件仍起作用而不应过早的销毁他们。
如果需要去销毁被多个成员对象共享的变量的时候,这种情况会变得很复杂。这种情况下,可以使用引用计数法来跟综访问着共享对象的代码数量,代码如下:
import static net.mindview.util.Print.*; class Shared { private int refcount=0; //标识引用该变量的个数 private static long counter=0; private final long id=counter++; //标识Shared变量 public Shared() { print("Creating "+this); } public void addRef() { refcount++; } protected void dispose() { if(--refcount==0) { print("Disposing "+this); } } public String toString() { return "Shared"+id; } } class Composing { private Shared shared; private static long counter=0; private final long id=counter++; public Composing(Shared shared) { print("Creating "+this); this.shared=shared; this.shared.addRef(); } protected void dispose() { print("disposing "+this); shared.dispose(); } public String toString() { return "Composing"+id; } } public class ReferenceCounting { public static void main(String[] args) { Shared shared=new Shared(); Composing[] composing={new Composing(shared),new Composing(shared), new Composing(shared),new Composing(shared)}; for(Composing c:composing) { c.dispose(); } } }
二、构造器内部的多态方法的行为
如果调用构造器内部的一个动态绑定的方法的时候,就需要用到那个方法被覆盖后的定义,动态绑定的方法调用导出类的方法,此时导出类成员变量还未被初始化,可能会产生错误。
public class Test { public static void main(String[] args) { new NewSon().print(); } } abstract class Father { String fs="Dad!"; public Father() { print(); } public abstract void print(); } class NewSon extends Father { int i=4; String ss="son!"; public void print() { System.out.println("Son.."+i); // System.out.println(ss.toUpperCase()); error } }
小细节:如果一个类实现了一个接口,同时继承了另外一个类,如果被继承的类有和接口中同样方法签名的方法,那么子类可以不用提供对于方法的实现。父类继承过来的方法相当于在子类中实现了接口。
interface Eat { public void eat(); } class Dog { public void eat() { } } public class BadDog extends Dog implements Eat {}
三、内部类的一些细节
1.如果在内部类生成对外部类的引用,可以通过外部类的名字加上.this,这样产生的引用会自动具有正确的开销.但是.this只能在外部类内部和内部类使用,其他类里不能使用.
2.在匿名内部类中,如果基类需要一个有参数的构造器,也可以传递参数给基类的构造器,代码如下:
class Wrapping { private int i; public Wrapping(int x) { i=x; } public int value() { return i; } } class Parcel8 { public Wrapping wrapping(int x)/*传入基类构造器*/ { return new Wrapping(x) { public int value() { return 47*super.value(); } }; } }
3.接口中也可以声明内部类,接口中的内部类自动被声明为public 和 static的类型,甚至可以在内部类中实现外部接口.
interface Dog { public void bark(); class GoodDog implements Dog { @Override public void bark() { System.out.println("bark!"); } } }
4.在继承内部类的时候,指向外围类的秘密的引用必须也要被初始化,因此使用特殊的语法来明确说明这种关联:
class WithInner { class Inner{ int i=0; public Inner (int i) { this.i=i; } } } class InheritInner extends WithInner.Inner { public InheritInner(WithInner withInner, int i) { withInner.super(i); } }
5.当继承外部类的时候。内部类并没有什么变化,两个内部类完全是独立的个体,各自在各自的命名空间内。
四、为什么需要内部类
1.每个内部类都能独立的继承自一个接口的实现,无论外部类继承了什么类对于内部类没有任何影响。而由于内部类也可以使用外部类的成员,因此,内部类有效的实现了“多重继承”。
class GrandFather { protected int gf=3; } class Father extends GrandFather { protected int ft=2; class Son extends Father { protected int s=1; public void say() { System.out.println(gf+" "+ft+" "+s); } } }
2.利用内部类实现命令模式。
可以将命令模式中的命令类放入调用者的内部来实现命令模式,代码如下:
public class Test4 { public static void main(String[] args) { GreenHouseControl gh=new GreenHouseControl(); gh.new LightOn().execute(); gh.new LightOff().execute(); gh.new WaterOn().execute(); gh.new WaterOff().execute(); } } interface Command /*命令接口*/{ public void execute(); } class GreenHouseControl { private boolean light=false; class LightOn implements Command { @Override public void execute() { System.out.println("The light is on."); light=true; } } class LightOff implements Command { @Override public void execute() { System.out.println("The light is off."); light=false; } } private boolean water=false; class WaterOn implements Command { @Override public void execute() { System.out.println("The water is on"); water=true; } } class WaterOff implements Command { @Override public void execute() { System.out.println("The water is off"); water=false; } } }
对于内部类的知识原理性整理可参见:http://www.cnblogs.com/hlhdidi/p/5575607.html http://www.cnblogs.com/hlhdidi/articles/5575416.html