资源预览内容
第1页 / 共34页
第2页 / 共34页
第3页 / 共34页
第4页 / 共34页
第5页 / 共34页
第6页 / 共34页
第7页 / 共34页
第8页 / 共34页
第9页 / 共34页
第10页 / 共34页
亲,该文档总共34页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
不变对象与类:,不变对象: 指在实例化后其外部可见状态无法更改的对象。不变类: 生成不可变对象的类。 例如:不变类: Boolean, Byte, Character, Double, Float, Integer, Long, Short, String. 可变类: StringBuffer, java.util.Date 等不变对象的好处:只能处于一种状态,所以只要正确构造了它们,就决不会陷入不一致的状态。不必复制或克隆不变对象, 就能自由地共享和高速缓存对它们的引用;也可以高速缓存它们的字段或其方法的结果,而不用担心值会变成失效的或与对象的其它状态不一致。,它们本来就是线程安全的,所以不必在线程间同步对它们的访问。这可以极大地简化编写并发程序的过程,并减少程序可能存在的潜在并发错误的数量。线程安全问题发生在当多个线程正在试图并发地修改一个对象的状态(写-写冲突)时,或当一个线程正试图访问一个对象的状态,而另一个线程正在修改它(读-写和写-读冲突)时。要防止这样的冲突,必须同步对共享对象的访问,以便在对象处于不一致状态时其它线程不能访问它们。 类不变条件:所有成员都是private。不提供对成员的修改器方法(setXXXX)。没有可变成员的访问器方法(可变成员引用 getXXXX),举例:三条件缺一不可,public class T9ChangableClass public static void main(String args) ChangableClass c = new ChangableClass(original value); System.out.println(c.getSB().toString(); c.getSB().append( is changed); System.out.println(c.getSB().toString(); class ChangableClass private StringBuilder sb; public ChangableClass(String sb) this.sb = new StringBuilder(sb); public StringBuilder getSB() return sb; ,本例的类具备前两条件,即类ChangableClass属性全部私有,且无setter。但对象构造后内容仍可变-状态可变!。,this引用:,代指实例本身的引用。因而,与类的实例有关。作用一:当方法中的局部变量与实例变量同名时,实例变量被隐藏,为访问该实例变量,需要在实例变量名前加this引用。作用二:用在构造器中,调用重载的构造器。 this(参数表);/调用有参构造 或 this(); /调用无参构造调用构造器时必须在其他语句前出现,否则编译错误!Super() 也不行!有参构造必须显式调用!举例(作用二):测试如下内容隐含this (用于限定构造器中的变量)显式this调用重载构造器(无参中均先调用有参)默认无参构造器调用及顺序 无参中均先调用有参是否导致父类构造器重复调用?!,public class T9This public static void main(String args) Son son = new Son(); /用无参构造器生成实例 class Grandfather private String name = = grandPa; public Grandfather() /无参构造器,隐式调用 this(grandfather); System.out.println(name); public Grandfather(String name) /有参构造器,须显式调用 System.out.print(name); ,class Father extends Grandfather private String name = =dadi; public Father()/无参构造器,隐式调用 this(father); System.out.println(name); public Father(String name)/有参构造器,须显式调用 System.out.print(name); class Son extends Father private String name =son; public Son() this(son); System.out.println(name); public Son(String name) System.out.print(name); ,使用无参构造时:调用父类无参构造器时刻,使用有参构造时:调用父类无参构造器时刻,只使用无参构造器时的运行结果。父类构造器隐式调用,并按继承层次上从上到下顺序构造。子对象的构造包含父对象的构造。父类无参构造器只会调用一次!子类无参构造器调用自己的有参构造器不会导致两次隐式调用父类无参构造。,将 Son son = new Son(); 换成: Son son = new Son(“child”);运行结果。同样,隐式调用父类构造器。,问题:下述程序执行结果?,class Teacher int var; Teacher(double var) this.var = (int)var; Teacher(int var) this(hello); Teacher(String var) this(); System.out.println(var); Teacher() System.out.println(good bye!); public static void main(String args) Teacher t = new Teacher(5); ,super关键字:,子类构造时要隐式调用父类的无参构造器,能否显式调用父类的构造器去初始化父类呢?如能,则对父类对象的初始化可依据需要灵活进行。 super指当前对象的父类的关键字。一定想要在子类中访问继承父类的同名属性,使用super.属性名来访问(问题:不同名如何?)访问父类被子类覆盖的方法也用super.方法名 (问题:未被子类覆盖的方法如何?)Super 和this不同,它不是引用!Super只限于子类内部使用; this 可传到类的外部去!,使用super:,public class T9UsingSuper public static void main(String args) UsingChild t = new UsingChild(); System.out.println(t.getSuperField(); System.out.println(t.callSuperMethod(); class UsingParent String name; UsingParent(String name) this.name = name; String getName() return name; ,class UsingChild extends UsingParent /子类全覆盖父类成分 String name =child; UsingChild()super(parent); /显式调用父类有参构造器 public String getName() return name; public String getSuperField() System.out.print(Return the field value of super: ); return super.name; /访问父类同名属性 public String callSuperMethod() System.out.print(Calling the method of super: ); return super.getName();/访问被子类覆盖的父类方法 ,完全同父类,可见不是子类构造器中使用super时,无第一条语句约束。显式调用父类构造器则必须第一条语句。,举例:测试this引用可赋值给其类类型的变量,public class T9AssignThis public static void main(String args) AssignThis t = new AssignThis(); AssignThis s = t.getThis(); System.out.println(s.name); class AssignThis public String name =Test; AssignThis as; AssignThis() as = this; public AssignThis getThis() return as; ,举例:测试super不是引用,public class T9AssignSuper public static void main(String args) AssignSuper t = new AssignSuper(); AssignParent s = t.getSuper(); System.out.println(s.name); class AssignParent public String name =Test;class AssignSuper extends AssignParent public AssignParent getSuper() return super; ,如是引用,则本方法应能执行(同上例一样),继承复用:如果想要一个类也具有另一个类的方法功能时,早期一般情况会采用将这个类去继承另一个类,这就是继承复用继承复用问题:继承一定是从一般到特殊的关系,父子类之间一定要是is-a的关系。而程序中的两个类不是/不一定是is-a的关系,不能直接设计为继承关系如果被继承的另一个类中有protected属性,那么在子类中就可以随意访问和修改,数据不安全,继承复用破坏了封装。(public更不用说!)对于被继承的另一个类中有些方法,子类不想要,但因继承却不得不要,破坏了子类的设计要求继承复用也称白盒复用, 其要破坏封装。,
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号