实现类重用 继承和组合比较
2011-11-16 10:23
183 查看
实现类重用:继承和组合。
继承:优点:子类可以获得父类的属性和方法,如果访问权限允许子类可以直接访问父类的属性和方法----------------相当于子类直接复用父类的属性和方法。
缺点: 1.与父类严重耦合 ,2.破坏父类得封装性
1.封装:每个类都应该封装它的内部信息和实现细节,而只是暴漏必要的方法给其他类使用,但在继承关系中,子类可以直接访问父类的属性(内部信息)和方法,从而造成了子类和父类的严重耦合。
2.父类的实现细节对子类是透明的,子类可以访问父类的属性和方法,并可以改变父类方法的实现细节(方法重写的方式改变父类方法的实现),从而导致子类可以恶意篡改父类的方法。
为保证父类良好的封装性,不会被子类随意改变,设计父类遵循如下规则:
1.隐藏父类内部数据,属性设置成private访问类型。
2.不要让子类随意访问,修改父类的方法。private:子类无法访问 public:外部类调用,如果不希望被子类重写,可以再用final修饰。 protected:希望父类方法被子类重写,不希望其它类自由访问。
3.尽量不要再父类构造器中调用将要被子类重写的方法:
Class Base{
public Base(){
test()-------------------------------------------1
}
public void test(){
System.out.println(“将被子类重写的方法");
}
}
Class Sub extends Base{
Private String name="aaaaaaaaaaaaaa";
public void test(){------------------------------------------------------------------2
System.out.println("子类重写父类的方法,其name的字符串长度"+name.length());
}
public static void main(String[] args){
//下面代码会引起空指针错误
Sub su = new Sub();
}
}
错误分析:
当系统视图创建Sub对象时,同样先执行其父类的构造器,如果父类的构造器调用了被子类重写的方法,并不是调用1号test方法,而是调用2号test方法,此时Sub对象的name属性是null,因此会引发空指针异常。
继承关系的把握:什么时候需要从父类派生出子类
1.子类需要额外增加属性,而不仅仅是属性值的改变。
2.子类需要增加自己独有的行为方式。
如果是出于类复用的目的,并不一定需要使用继承,完全可以使用组合来实现。不管是继承还是组合,都可以在新类(对于继承就是子类)中直接复用旧类的public方法。
如果两个类之间有明确的整体,部分的关系,用组合关系来实现复用。
继承与组合的选择: 继承表达的是 is-a关系 组合表达的是:has-a关系
继承:优点:子类可以获得父类的属性和方法,如果访问权限允许子类可以直接访问父类的属性和方法----------------相当于子类直接复用父类的属性和方法。
缺点: 1.与父类严重耦合 ,2.破坏父类得封装性
1.封装:每个类都应该封装它的内部信息和实现细节,而只是暴漏必要的方法给其他类使用,但在继承关系中,子类可以直接访问父类的属性(内部信息)和方法,从而造成了子类和父类的严重耦合。
2.父类的实现细节对子类是透明的,子类可以访问父类的属性和方法,并可以改变父类方法的实现细节(方法重写的方式改变父类方法的实现),从而导致子类可以恶意篡改父类的方法。
为保证父类良好的封装性,不会被子类随意改变,设计父类遵循如下规则:
1.隐藏父类内部数据,属性设置成private访问类型。
2.不要让子类随意访问,修改父类的方法。private:子类无法访问 public:外部类调用,如果不希望被子类重写,可以再用final修饰。 protected:希望父类方法被子类重写,不希望其它类自由访问。
3.尽量不要再父类构造器中调用将要被子类重写的方法:
Class Base{
public Base(){
test()-------------------------------------------1
}
public void test(){
System.out.println(“将被子类重写的方法");
}
}
Class Sub extends Base{
Private String name="aaaaaaaaaaaaaa";
public void test(){------------------------------------------------------------------2
System.out.println("子类重写父类的方法,其name的字符串长度"+name.length());
}
public static void main(String[] args){
//下面代码会引起空指针错误
Sub su = new Sub();
}
}
错误分析:
当系统视图创建Sub对象时,同样先执行其父类的构造器,如果父类的构造器调用了被子类重写的方法,并不是调用1号test方法,而是调用2号test方法,此时Sub对象的name属性是null,因此会引发空指针异常。
继承关系的把握:什么时候需要从父类派生出子类
1.子类需要额外增加属性,而不仅仅是属性值的改变。
2.子类需要增加自己独有的行为方式。
如果是出于类复用的目的,并不一定需要使用继承,完全可以使用组合来实现。不管是继承还是组合,都可以在新类(对于继承就是子类)中直接复用旧类的public方法。
如果两个类之间有明确的整体,部分的关系,用组合关系来实现复用。
继承与组合的选择: 继承表达的是 is-a关系 组合表达的是:has-a关系
相关文章推荐
- 二十四、继承(一) 代码重用、继承方式、接口继承与实现继承、继承和重定义、继承和组合
- 关于泛化、继承、实现、关联、聚合、组合、依赖关系比较
- 面向对象,类的组合关系,继承,实现,方法重写,方法重载,this的使用,抽象方法和抽象类的比较,父类构造方法存在的意义,多态的是用和解析,各种访问修饰符
- 面向对象编程中的继承和组合的简单比较
- 继承、实现、依赖、关联、聚合、组合
- 类与类之间的几种关系(继承、实现、依赖、关联、聚合、组合)
- 关联,依赖,泛化(又称继承分为扩展或包含),实现,聚合(共享),复合(组合)
- UML中几种类间关系:继承、实现、依赖、关联、聚合、组合的联系与区别
- UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)
- 继承,实现,关联,聚合,组合,依赖几种关系的介绍
- UML中几种类间关系:继承、实现、依赖、关联、聚合、组合的联系与区别-转载
- UML中几种类间关系:继承、实现、依赖、关联、聚合、组合的联系与区别
- 继承、实现、依赖、关联、聚合、组合的联系与区别
- UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)-转
- 架构漫谈:UML中几种类间关系:继承、实现、依赖、关联、聚合、组合的联系与区别
- UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)
- UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)
- 继承、实现、依赖、关联、聚合、组合的联系与区别
- 继承、实现、依赖、关联、聚合、组合的联系与区别
- UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)