个人理解设计为何要多用组合,少用继承
- 子类对父类的继承是全部的公有和受保护的继承,这使得子类可能继承了对子类无用甚至有害的父类的方法。换句话说,子类只希望继承父类的一部分方法,怎么办?
- 实际的对象千变万化,如果每一类的对象都有他们自己的类,尽管这些类都继承了他们的父类,但有些时候还是会造成类的无限膨胀。
- 继承的子类,实际上需要编译期确定下来,这满足不了需要在运行内才能确定对象的情况。而组合却可以比继承灵活得多,可以在运行期才决定某个对象。
public class ListMap extends HashMap {
private List list;
public ListMap() {super();this.list = new ArrayList();
}
public Object put(Object key,Object value)
{if(list.contains(key)){list.remove(key);}this.list.add(key);return super.put(key,value);
}
public Object getKey(int i)
{return this.list.get(i);
}
public Object getValue(int i)
{return this.get(getKey(i));
}
public int size()
{return this.list.size();
}
}
这个ListMap类就可以放心的使用了吗?实现了这样功能的类,你的同事或朋友也可能把这个类拿来使用一下,他可能写出来如下的代码:
ListMap map = new ListMap();map.put("a","111");map.put("v","190");map.put("d","132");String[] list = (String[])map.values().toArray(new String[0]);for(int i=0;i<list.length;i++){System.out.println(list[i]);}
public class MyListMap {
private HashMap map;
private List list;
public MyListMap()
{this.map = new HashMap();this.list = new ArrayList();
}
public Object put(Object key,Object value)
{if(list.contains(key)){list.remove(key);}this.list.add(key);return this.map.put(key,value);
}
public Object getKey(int i)
{return this.list.get(i);
}
public Object getValue(int i)
{return this.map.get(getKey(i));
}
public int size()
{return this.list.size();
}
}
public interface WhatIHave
{public void g();
}
public class Resource
{public void f(){……}public void h(){……}
}
上面是两个基础类,很明显,我们所要的类既要有g()方法,也要有f()和h()方法。
Public class WhatIWant implements WhatIHave
{private Resource res;public WhatIWant(){res = new Resource();
}
public void g()
{……
}
public void f()
{this.res.f();
}
public void h()
{this.res.h();
}
}
上面就是一个Adapter模式最简单的解决问题的思路。对于Resource类,该模式使用的是组合,而不是继承。这样使用是有多个原因:第一,Java不支持多重继承,如果需要使用好几个不同的Resource类,则继承解决不了问题。第二,如果Resource类还有一个方法:k(),我们在WhatIWant类里使用不上的话,继承就给我们造成多余方法的问题了。
如果说Adapter模式对组合的应用的目的十分简单明确,那么Decorator模式对组合的应用简直就是令人叫绝。
public interface Product{
public double money();
}
咖啡类:
public class Coffee implements Product{public double money() {return 12;}
}
加糖:
public class Sugar implements Product{private Product product;public Sugar(Product product) {this.product = product;}public double money(){return product.money+2;}
}
加冰:
public class Ice implements Product{private Product product;public Ice(Product product) {this.product = product;}public double money(){return product.money+1.5;}
}
加奶:
public class Milk implements Product{private Product product;public Milk(Product product) {this.product = product;}public double money(){return product.money+4.0;}}
加巧克力:
public class Chocolate implements Product{private Product product;public Chocolate(Product product) {this.product = product;}public double money(){return product.money+5.5;}
}
Product prod = new Coffee();
System.out.println(prod.money());
Product prod = new Ice(new Coffee());
System.out.println(prod.money());
Product prod = new Chocolate(new Milk(new Ice(new Sugar())));
System.out.println(prod.money());
个人理解设计为何要多用组合,少用继承相关推荐
- 【Java设计模式 面向对象设计思想】五 多用组合少用继承编程
我们经常会听到说多用组合少用继承,但是拜托,继承是面向对象四大特性之一啊,为什么地位反不如组合了呢,为什么不推荐使用继承?组合相比继承有哪些优势?如何判断该用组合还是继承?围绕这三个问题进行以下讨论 ...
- 为何说要多用组合少用继承?
在面向对象编程中,有一条非常经典的设计原则,那就是:组合优于继承,多用组合少用继承.为什么不推荐使用继承?组合相比继承有哪些优势?如何判断该用组合还是继承?今天,我们就围绕着这三个问题,来详细讲解一下 ...
- 理论七:为何说要多用组合少用继承?如何决定该用组合还是继承?
在面向对象编程中,有一条非常经典的设计原则,那就是:组合优于继承,多用组合少用继承.为什么不推荐使用继承?组合相比继承有哪些优势?如何判断该用组合还是继承?今天,我们就围绕着这三个问题,来详细讲解一下 ...
- 为什么要多用组合少用继承?
面向对象编程时,有十条很重要的原则: 代码复用 封装变化 开闭原则 单一职责原则 依赖注入/依赖倒置原则 里氏替换原则(LSP) 接口隔离原则(ISP) 多用组合,少用继承 面向接口编程 委托原则 上 ...
- 在设计原则中,为什么反复强调组合要优于继承?
今日推荐21 款 yyds 的 IDEA插件这 56 个代码注释让我笑吐了注解+反射优雅的实现Excel导入导出(通用版)Fluent Mybatis 牛逼!Nginx 常用配置清单这玩意比Threa ...
- 从认知角度去理解设计
设计并不是一味只求美感或者感觉,设计同样是一门建立在多学科基础上的科学,从认知角度来理解设计能帮助我们设计出更多尊重用户的作品,这样的设计才能经得起时间的考验,让更多用户所喜爱. 下面是我对<认 ...
- 【总结记录】面向对象设计OOP三大特性(封装、继承、多态)、七大基本原则的理解(结合代码、现实实例理解)
文章目录 一. 三大特征的理解 (1)封装 (2)继承 (3)多态 (4)面向对象.面向过程的对比 二. 七大基本原则的理解 (1)单一职责原则 (2)开放封闭原则(OOP 核心) (3)里氏替换原则 ...
- 交互设计实用指南系列11-减少记忆负担
http://ued.taobao.org/blog/2010/03/交互设计实用指南系列11-减少记忆负担/ 科普 <辞海>中"记忆"的定义是:"人脑对经验 ...
- 面向对象设计原则——优先使用对象组合,而不是继承(组合以及与继承的区别)
看到面向对象设计原则中的合成复用原则: 优先使用对象组合,而不是继承 类继承:也叫白箱复用 对象组合:也叫黑箱复用. 继承某种程度上破坏了封装性,子父类之间的耦合性过高. 对象组合只要求被组合的对象具 ...
- 程矢Axure夜话:程序员眼中的原型设计视频教程之书到用时方恨少
程矢Axure夜话:程序员眼中的原型设计视频教程之书到用时方恨少 案例描述:书到用时方恨少 这是一个经典的案例,作者曾经在培训机构工作期间发现很多的学员都很喜欢这样的课程 知识点: 动态面板的移动 动 ...
最新文章
- 请你描述一下 cookies,sessionStorage 和 localStorage 的区别?
- Java API帮助文档怎么查找?
- 卷积神经网络迁移学习
- 全局路径规划:图搜索算法介绍2(A star)
- vuex页面数据丢失_解决 vuex 中的数据在页面刷新之后就丢失的问题
- 设计模式之单例模式8种实现方式,其八:枚举方式
- 向前的快捷键_平面设计基础知识:平面设计师应该知道的快捷键。
- Leetcode 279 完美平方数
- Java~基于fluent-hc快速构建Http请求,结合failsafe实现异常重试
- 10个互联网兼职平台,让你的一技之长变现,副业薪资比日常搬砖高也太爽了
- C++语句 与简单方法
- Java程序语言(基础篇)第2章 基本程序设计 编程练习题解答
- nihao, woshi mr jhon
- 使用 @mention 功能构建 React 评论表单
- android平台下OpenGL ES 3.0绘制圆点、直线和三角形
- 京东12年被裁,昨天赔偿到账了,加调休和年假总共47万多,感谢公司!
- 二叉树先序遍历(递归+迭代)——java
- [OC学习笔记]块与大中枢开发
- 伯努利分布、二项分布、泊松分布、指数分布简介
- 【Java】多态的理解与使用
热门文章
- vc语言c1083错误,VC Fatal Error C1083的几种解决方案
- 使用ireport创建报表模板时,向subdataset中传参
- 计算机网络在信息时代的作用
- 『一篇老文章』现有p2p协议分类与简介
- oracle 数据库不用了,改用SQL,要学SQL了,第一个手工写的存储过程
- 手把手教你怎样用U盘装系统
- oracle加减乘除怎么写,加减乘除怎么写-加减乘除的名称怎么写-加减乘除的笔画怎么写...
- java程序员 thinkpad_JAVA程序员笔记本电脑推荐?
- 淘宝商品评论获取评论
- Echarts直角坐标系x轴y轴属性设置大全