标签:
在清理方法中,还必须注意对基类清理方法和成员对象清理方法的调用顺序,以防止某个子对象依赖于另一个子对象的情形的发生.一般而言,首先执行类的所有特定清理动作,其顺序同生成顺序相反(通常这要求基类元素仍然存活.然后再调用基类的清理方法.
Java允许在参数列表中以声明的方式将参数声明为final.这意味着无法在方法中更改参数的值.(引用无法更改参数指向的对象).
类中所有的private方法都隐式的被指定为final的,由于无法取用private方法,所以也就无法覆盖它.可以给private方法添加final修饰词,但这并不能给方法增加额外的意义.覆盖只有在能将一个对象向上转型并调用它的方法的时候才会出现,如果方法是private,则它不是基类接口的一部分,仅仅是隐藏与类中的程序代码,当声明一个public protected和包访问权限的方法的话,该方法不会产生在基类中出现的仅仅具有相同名称的情况.此时并没有覆盖方法,仅仅是生成了一个新的方法.下面的代码说明了这个问题:
public class Dad { private void say() { System.out.println("I am Dad"); } public static void main(String[] args) { Dad d=new Son(); //子类的Public访问权限的say相当于定义在子类的全新的方法,不符合动态绑定的情况,仍然使用父类的say方法 d.say();//输出I am Dad } } class Son extends Dad{ public void say() { //在子类中无法访问父类的private方法,private包装在子类对象内部的父类对象内,无法访问. //super.say();错误.无法访问,类的访问权限. System.out.println("I am son."); } }
下面的代码提供了初始化的示例:
import static net.mindview.util.Print.*; class Insect { private int i=9; protected int j; Insect() { print("i="+i+"j="+j); j=39; } private static int x1=printInit("static Insect.x1 initialized."); static int printInit(String s) { print(s); return 47; } } public class Beetle extends Insect{ private int k=printInit("Bettle.k initialized"); public Beetle() { print("k="+k); print("j="+j); } private static int x2=printInit("static Bettle.x2 initialized"); public static void main(String[] args) { print("Beetle constructor:"); Beetle b=new Beetle(); } }
首先在Beetle上运行Java的时候,视图访问Beetle.main,于是加载器开始启动并找出Beetle类的编译代码,在对它进行加载的过程中,编译器注意到它有一个基类,于是它继续进行加载,不管是否打算产生一个基类的对象,这都会发生.
接下来,根基类的static元素会被初始化,然后是下一个子类,以此类推.这种方式很重要,因为子类的static初始化可能会依赖于基类成员是否被正确初始化.至此,必要的类加载完毕,对象就可以创建了.首先对象中所有的基本类型都会设为默认值,对象的引用被设为null-然后基类的构造器会被调用,基类构造器和子类的一样,以相同的顺序经历相同的过程,在基类构造器完成后,实例变量按次序被初始化.最后,构造器的其余部分被执行.
只有普通的方法调用才可以是多态的.如果直接访问某个域,这个访问就在编译器开始进行解析:
class Super { public int field=0; public int getField() { return field; } } class Sub extends Super { public int field=1; public int getField() { return field; //相当于return this.field. } } public class Test3 { public static void main(String[] args) { Super sup=new Sub(); System.out.println("sup.field="+sup.field+",sup.getField="+sup.getField()); //sup.field=0,sup.getField=1 } }
当Sub对象转型为Super引用的时候,任何域访问操作都将有编译器解析,因此不是多态的.Sub实际上包含两个称为field的域,它自己的和从Super处得到的.而在引用Sub中的field域时候所产生的默认域并非Super版本的field域.
标签:
原文地址:http://www.cnblogs.com/hlhdidi/p/5657781.html