thinking in java笔记 7 复用类

  • 组合
    编译器并不是简单的为每一个引用都创建默认对象,这样可以减少很多不必要的负担。如果想初始化这些引用,可以在如下位置进行:
    1 在定义对象的地方
    2 在类的构造器中
    3 在使用对象之前(惰性初始化)
    4 使用实例初始化
  • 继承
     创建类时总是在继承,若未明确指出从其他类继承,则默认继承Object。
     其他包中的继承类只能访问父类的public成员和方法,一般将父类成员设为private,方法设为public.
     在继承类中可以调用父类的方法,方法名相同时,前面加super关键字进行调用。
     从外部看,导出类像是一个与基类具有相同接口的新类,或许还会有额外的方法和域,但继承并不只是复制基类的接口。当创建了一个导出类的对象时,该对象包含了一个基类的子对象。java会自动在导出类的构造器中加入对基类构造器的调用。如果没有默认的基类构造器,必须显式调用基类的含参构造器。
  • 代理
      java没有提供直接支持,是继承和组合的中庸之道。
      将一个成员对象置于索要构造的类中(类似组合),但同时在新类中暴露了该成员对象的所有方法(类似继承)。使用代理时可以拥有更多的控制力,可以选择只提供成员对象方法中的某个子集。
public class DirectionControls {
void left( int i){}
void right( int i){}
void forward( int i){}
void back( int i){}
}

public class Car {
DirectionControls controls= new DirectionControls();
void left( int i){
controls.left(i);
}
void right( int i){
controls.right(i);
}
public static void main(String[] s){
Car car= new Car();
car.left(1);
}
}


  • 确保正确清理
    有时必须显式编写一个方法来做清理活动,因为不知道gc何时才会执行,清理过程必须放在finally子句之中。继承结构中,清理动作应与对象生成顺序相反,先调用子类的,再调用基类的。
  • @ override
    java在导出类中定义同名方法不会屏蔽基类中的版本,在导出类中和基类中重载机制都有效。想要覆写基类的某个方法时,添加@Override标记,防止不想重载而意外进行了重载的状况,override也不会屏蔽基类的版本。注意事项如下:
override(重写)
 
1、方法名、参数、返回值相同。(子类方法返回值类型为父类方法的子类型可以)
2、子类方法不能缩小父类方法的访问权限。
3、子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。
4、存在于父类和子类之间。
5、方法被定义为final(包含private)不能被重写。
overload(重载)
1、参数类型、个数、顺序至少有一个不相同。  
2、不能重载只有返回值不同的方法名。
3、存在于父类和子类、同类中。
  • 组合与继承
    两者都允许在新的类中放置子对象,组合显式,继承隐式。
    组合通常用于想在新类中使用现有类的功能而非接口的情形。是has-a关系。
    继承使用现有类(通用类),并开发一个特殊版本(特殊化)。是is-a关系。
    在OOP中,最可能用的是直接将数据和方法包装进一个类中,然后使用此对象。也可以运用组合使用现有类来开发新的类,但继承是不常用的。判断使用组合还是继承,最好地方法是判断是否需要从新类向基类进行向上转型操作。
  • protected
    作用是将某些事物尽可能对这个世界隐藏,但仍允许导出类的成员访问它们(有包访问权限)。
    尽管可以创建protected域,但更好的方式是域为private,通过protected方法控制导出类的访问权限。(为自己保留更改底层实现的权利)
  • 向上转型
    由于继承可以确保基类中所有的方法在导出类中同样有效,所有能够向基类发送的所有消息同样也可以向导出类发送。将导出类引用转换为基类引用的动作称为向上转型。导出类是基类的一个超集,向上转型时,类接口中可能会丢失方法,但是是安全的。
  • final
    final是指“这是无法改变的”,原因可能为:设计或效率。由于两者差之甚远,因此可能被误用。final使用的情况:数据、方法和类。
    final数据:
      通常用途 1 一个永不改变的编译时常量 2 一个在运行时被初始化的值,而你不希望它被改变。
      一个static final域只占据一段不能改变的存储空间。域名全部大写,用_隔开。
      对于基本类型,final使数值恒定不变,对于对象引用,final使引用恒定不变。一旦初始化指向一个对象,就不能指向另外的对象,但对象本身的值是可以改变的。
      空白final:被声明为final但未给定初值的域。它使得类中的final域可以根据对象不同而有所不同,但又保持恒定不变。如在构造函数内根据参数进行初始化。
    final参数:
      可以在参数列表中将参数声明为final,在方法中无法更改参数引用所指向的对象。这一特性主要向匿名内部类传递数据。
    final方法:
      原因:把方法锁定,防止继承类修改,确保在继承中使方法行为保持不变,并且不会被覆盖。
      private方法都隐式地制定为final。
    final类:
      类定义为final时,此类不可被继承。对类的设计永不需要做任何变动,或者出于安全考虑,不希望它有子类。final类的域不受类的final影响,而final类中的方法因不可继承,默认全是final的,不管有没有final关键字。
  • 初始化及类的加载
    java不会出现static变量之间加载顺序的依赖问题。java的所有事物都是对象,每个类的编译代码都存在于独立的文件中,该文件只在需要使用程序代码时才会加载。构造器也是static方法,类是在其任何static成员访问时加载的。
    加载顺序:
     0 .   在做任何事情之前,将分配给对象的存储空间,初始化成二进制的0,或null。
     1.    父类静态成员和静态初始化块  ,按在代码中出现的顺序依次执行

     2.    子类静态成员和静态初始化块  ,按在代码中出现的顺序依次执行

     3.    父类实例成员和实例初始化块  ,按在代码中出现的顺序依次执行

     4.    父类构造方法

     5.    子类实例成员和实例初始化块  ,按在代码中出现的顺序依次执行

     6.    子类构造方法

 

posted @ 2011-10-09 17:30  因是因非  阅读(224)  评论(0编辑  收藏  举报