继承是实现类重用的重要手段,但是它有一个最大的坏处:破坏封装。相比之下,组合也是实现类重用的重要方式,但是采用组合方式实现类重用则能提供更好的封装性。比如人有手一样,在人的类中增加一个手的属性。
- 何时使用继承呢:
1,子类需要增加额外的属性,不仅仅是属性值的改变
2,子类需要增加自己独有的行为方式
- 为了保证父类有良好的封装性,不会被子类随意改变,设计父类通常应该遵循以下规则:
1,尽量隐藏父类的内部数据。尽量把父类的所有属性都设置成private访问类型,不要让子类直接访问父类的属性
2,不要让子类可以随意访问,修改父类的方法。
父类中那些仅为辅助其他的工具方法,应该使用private访问控制符修饰,让子类无法访问该属性。
如果父类中的方法需要被外部类调用,则必须是public修饰,但是又不希望子类重写这个方法,可以使用final修饰符来修饰。
如果希望父类的某个方法被子类重写,但不希望被其他类*访问,使用protected修饰。
3,尽量不要再父类构造器中调用将要被子类重写的方法。下面代码演示这个可能陷入的误区:
/**
*
* @version 1L
* @author LinkinPark
* @since 2014-10-28
* @motto 梦似烟花心似水,同学少年不言情
* @desc ^在写继承的时候 注意构造器可能造成的误区:尽量不要再父类构造器中调用将要被子类重写的方法
*/
public class SubClass extends BaseClass{
private String name; @Override
public void test(){
System.out.println(name.length());
} public static void main(String[] args) {
//这里在new这个子类对象的时候,实际上调用了子类重写的Test方法,那么这个时候name是null,下面代码将造成空指针异常
SubClass linkin = new SubClass();
}
} class BaseClass{
//在new一个子类的时候,将调用这个默认的无参的构造器
public BaseClass(){
test();
}
public void test(){
System.out.println("1");
}
}
- 那么什么时候继承,什么时候使用组合呢?
一般 → 特殊:继承关系,是"is a"关系,Java通过extends表示这种关系。
整体 → 部分:组合关系,Java语言通过在一个类中保存另一个对象的引用实现这种关系。是"has a"关系。
注意:上面2者的系统开销一样的,即使是继承也会为父类属性开辟内存空间的。