黑马程序员技术交流社区

标题: java继承与组合 [打印本页]

作者: 影响力147753321    时间: 2013-5-26 10:38
标题: java继承与组合
继承和组合这二个概念是怎么定义的,有什么区别?什么时用继承,什么时用组合?
作者: ZhaoYuBetter    时间: 2013-5-26 10:44
组合是has a,继承是is a; 什么时候用,等到高手来回答
作者: 谢孔营    时间: 2013-5-26 11:35
本帖最后由 谢孔营 于 2013-5-26 11:37 编辑

概念来自度娘
自己的理解:
组合是一种包含的关系,有点内部对象的意思
例如
一个电脑是一个对象,显卡是一个对象,显卡在电脑内部,所以定义电脑类的同时内部有一个对象来定义显卡
这就是组合。
class XianKa {
  //........
}

class Computer{
    privte XianKa xk;
}
继承就是子类扩展父类的功能。
组合

通过创建一个由其他对象组合的对象来获得新功能的重用方法
新功能的获得是通过调用组合对象的功能实现的
有时又叫聚合
组合的优缺点

优点
被包含对象通过包含他们的类来访问
黑盒重用,因为被包含对象的内部细节是不可见的
很好的封装
每个类专注于一个任务
通过获得和被包含对象的类型相同的对象引用,可以在运行时动态定义组合的方式
缺点
结果系统可能会包含更多的对象
为了使组合时可以使用不同的对象,必须小心的定义接口
例如:
一个对象拥有或者对另外一个对象负责并且两个对象有相同的生命周期。(GOF)
一个对象包含另一个对象集合
被包含对象对其他对象是不可见的并且只能从包含它的对象中访问的特殊组合形式
继承的优缺点

优点
新的实现很容易,因为大部分是继承而来的
很容易修改和扩展已有的实现
缺点
打破了封装,因为基类向子类暴露了实现细节
白盒重用,因为基类的内部细节通常对子类是可见的
当父类的实现改变时可能要相应的对子类做出改变
不能在运行时改变由父类继承来的实现
由此可见,组合比继承具有更大的灵活性和更稳定的结构,一般情况下应该优先考虑组合。只有当下列条件满足时才考虑使用继承:

子类是一种特殊的类型,而不只是父类的一个角色
子类的实例不需要变成另一个类的对象
子类扩展,而不是覆盖或者使父类的功能失效
作者: First    时间: 2013-5-26 11:57
  1. /*装饰者设计模式与继承的比较

  2. MyReader//专门用于读取数据-----继承的结构
  3.         |--MyTextReader
  4.                 |--MyBufferTextReader
  5.         |--MyMediaReader
  6.                 |--MyBufferMediaReader
  7.         |--MyDataReader
  8.                 |--MyBufferDataReader

  9. class MyBufferReader
  10. {
  11.         MyBufferReader(MyTextReader text){
  12.         }

  13.         MyBufferReader(MyMediaReader text){
  14.         }

  15.         MyBufferReader(MyDataReader text){
  16.         }
  17. }
  18. 该类的扩展性很差,
  19. 找到其参数的共同类型,通过多态形式通过扩展性

  20. class MyBufferReader extends MyReader                //继承公共父类,即MyReader,而不像继承结构中-继承MyReader的子类
  21. {
  22.         MyBufferReader(MyReader r){
  23.         }
  24. }

  25. MyReader//专门用于读取数据的类-----装饰模式的结构
  26.         |--MyTextReader
  27.         |--MyMediaReader
  28.         |--MyDataReader
  29.         |--MyBufferReader     //组合结构

  30. */


  31. import java.io.*;

  32. class MyBufferedReader extends Reader
  33. {
  34.         private Reader fr = null;
  35.         MyBufferedReader(Reader fr){
  36.                 this.fr = fr;
  37.         }

  38.         public String myReadLine() throws IOException{
  39.                 StringBuilder sb = new StringBuilder();   //StringBuilder();
  40.                 int ch = 0;
  41.                 while ((ch = fr.read())!= -1)
  42.                 {
  43.                         if (ch=='\r')
  44.                                 continue; // the keyword continue.
  45.                         if(ch == '\n')
  46.                                 return sb.toString();
  47.                         sb.append((char)ch);
  48.                 }
  49.                 if (sb.length() != 0)
  50.                         return sb.toString(); //important to return the last line.
  51.                
  52.                 return null;
  53.         }

  54.         public int read (char[] buf, int off, int len) throws IOException{
  55.                 return read (buf, off, len);                //调用对象方法
  56.         }

  57.         public void close() throws IOException{
  58.                 fr.close();                        //调用对象方法
  59.         }

  60.         public void myClose() throws IOException{
  61.                 fr.close();
  62.         }

  63. }

  64. class MyBufferedReaderDemo{

  65.         public static void main(String[] args) throws IOException
  66.         {
  67.                 FileReader fr = new FileReader("buf.txt");
  68.                 MyBufferedReader mr = new MyBufferedReader(fr);
  69.                 String line = null;
  70.                 while ((line = mr.myReadLine()) != null)
  71.                 {
  72.                         System.out.println(line);
  73.                 }
  74.                 System.out.println("Hello World!");
  75.         }
  76. }
复制代码
毕老师是视频在第19天。

装饰和继承的区别




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2