探讨继承与实现(二)
2007年2月1日
http://www.cnblogs.com/birdshover/
目录:
一、抽象的产生
二、依赖抽象
三、抽象的损耗
一、抽象的产生
你不知道你要实现的是个什么东西,你能很好的抽象出来么?我不是天才,所以我是不能。如果是那些天才至少也要是白痴天才型的人才能在毫无根据的情况下,假设出真是的存在。尔后居然被伟人证实居然是真的。比如说那个什么××××猜想。
我认为,抽象要么是在建立模型后的产物,要么是重构的结果。而抽象是为了解决程序未来面临的变动。但是你即便把实体抽象出来了,不使用也是没有效果的。而前人总结出经验如何使用这些抽象产物——依赖倒置(Dependence Inversion Principle)。讲的是:要依赖于抽象,不要依赖于具体。也就是经常说的面向接口编程。(这地方的接口是广义上的接口)
图2.1 抽象的产生与运用
上图描绘了先是根据细节得出抽象描述,然后又把抽象描述运用于实例。从种看出,如果没有3,4两步,抽下是没有意义的。就好比先发现了电,然后发现两根电线能传输电,再后来把电器接在电线上。但是这样很麻烦,于是发明了插座。再把插座实际应用到流程中去。
假设公司装了一扇自动门,有人来会开,人走了就关上。
2 {
3 private bool HavaPeson = false; //是否有人,默认没有。自动门,该状态会自动改变。
4
5 public void Open()
6 {
7 if (HavaPeson)
8 Console.WriteLine("Opend");
9 }
10
11 public void Close()
12 {
13 if (!HavaPeson)
14 Console.WriteLine("Closed");
15 }
16 }
我们把它抽象出来
2 {
3 void Close();
4 void Open();
5 }
2 {
3 private bool HavaPeson = false;
4
5 public void Open()
6 {
7 if (HavaPeson)
8 Console.WriteLine("Opend");
9 }
10
11 public void Close()
12 {
13 if (!HavaPeson)
14 Console.WriteLine("Closed");
15 }
16 }
但是这对我们好像并没有用。
这个时候公司又要装一扇门,手推才会开,不推自动关上。
二、依赖抽象
2 {
3 private bool IsPush = false;
4
5 public void Open()
6 {
7 if (IsPush)
8 Console.WriteLine("Opend");
9 }
10
11 public void Close()
12 {
13 if (!IsPush)
14 Console.WriteLine("Closed");
15 }
16 }
Door2也实现了IDoor接口啊!
所以改成
public class Door2 : IDoor
{}
老总感觉这两扇门不错,所以要全大楼装上这样的门,并且采用电脑控制。
如果每个门一个控制端,那累也累死了。所以可以实现如下。
图2.2 抽象关系
就是让ControlDoor依赖于IDoor。代码如下:
2 {
3 private IDoor[] door = new IDoor[100];
4 private bool flag = false; //判断门和人的关系状态
5
6 public void CDoor(int i)
7 {
8 door[i] = (IDoor)new Door();
9 Contorl(door[i]);
10 }
11
12 public void CDoor2(int i)
13 {
14 door[i] = (IDoor)new Door2();
15 Contorl(door[i]);
16 }
17
18 public void Contorl(IDoor d)
19 {
20 if (flag)
21 d.Open();
22 else
23 d.Close();
24 }
25 }
现在即使要加新的门,只要让新型号的门实现接口IDoor就可以了。当然,这地方使用接口而不是抽象类,是根据第一篇文章决定的。探讨继承与实现(一)
至于使用抽象类也是一样的道理。
三、抽象的损耗
所谓有所得必有所失,灵活的架构必然会带来性能上的损耗。
损耗的第一点,大家应该都看出来了,就是类型转换。需要把类的实例转换成接口或者抽象类。而转换除了带来灵活以外,并没有其它的收获。
2 {
3
4 #region ITest 成员
5 private int myint;
6 private string s;
7
8 public string otherStr
9 {
10 get
11 {
12 return s;
13 }
14
15 set
16 {
17 s = value;
18 }
19 }
20
21
22
23 public int MyInt
24 {
25 get
26 {
27 return myint;
28 }
29 set
30 {
31 myint = value;
32 }
33 }
34
35 public string MyStr()
36 {
37 return "myStr";
38 }
39
40 #endregion
41
42 public string OtherStr()
43 {
44 return otherStr;
45 }
46 }
2 {
3 int MyInt
4 {
5 get;
6 set;
7 }
8
9 string otherStr { get;set;}
10 string MyStr();
11 }
2 {
3 ITest it = (ITest)new Test();
4 Test t = (Test)it;
5 t.otherStr = "1";
6 it.otherStr = "2";
7 Console.WriteLine(t.OtherStr());
8 Console.ReadKey();
9 }
以上代码输出值 2
实例it不能使用方法OtherStr,而再转化回来后还能使用,证明内存种存在的是Test的实例。并没有因为ITest 没有OtherStr而砍掉。只是再it实例中屏蔽(简化)了我们的访问。
图2.3 类的转换前后
从图中可以看出,转换只是给了我们一个望远镜,一面能看到很大的视野,一面看到的小。就和古人写的管中窥豹是一个道理吧。
而为什么输出的是2而不是1,那是因为类是引用类型。而转换后还是引用类型。it和t看似两个实例,实际上指向的是同一段内存地址,只是留给你的看台不一样。
探讨继承与实现(二)相关推荐
- java三大特性 继承_java基础(二)-----java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- 继承和多态二:虚析构函数
虽然我们已经知道了什么是继承和多态,也明白了多态依赖于继承,但是在多态中存在哪些问题呢? 多态中可能存在的内存泄露问题 例如下面的程序中,在圆形Circle的类中定义一个圆心的坐标,并且坐标是在堆中申 ...
- ★深入探讨高维宇宙【二】
你相信宇宙是多维的吗?甚至是11维度,26维度? 2017-4-7 3:36:00 作者: 宇宙小百科 一个四维的正方体观察起来,是这个样子, 这种形态有一个专门的名字,叫做&qu ...
- C++之继承探究(十二):子类的构造、析构和赋值运算符重载
涉及到本文所讲知识点的博文: C++之析构函数探究 C++之常引用和浅拷贝探究 C++之一个函数链的简单例子(分文件实现) C++之Big Three:拷贝构造.拷贝赋值.析构函数探究 C++之操作符 ...
- Java基础--继承案例(二)
/*** 通过类来体现类与类之间的关系:* 1,创建动物类* 2,创建猫类* 3,创建狗类**/ public class InheritDemo {public static void main(S ...
- C#学习之面象对象继承练习(二)
1.里氏转换 using System; using System.Collections.Generic; using System.Linq; using System.Text; using S ...
- hibernate继承关系映射关系方法(二)--每个子类一张表
TPS:所谓"每个子类一张表(Table Per Subclass)":父类一张表,每个子类一张表,父类的表保存公共有信息,子类的表只保存自己特有的信息 这种策略是使用<jo ...
- OO真经——关于面向对象的哲学体系及科学体系的探讨(上)
http://www.cnblogs.com/leoo2sk/archive/2009/04/09/1432103.html 目录 Catelog 序言 Perface 真经第一章:世界 Waltan ...
- 探讨ASP.NET2.0中的Web控件改进技术
全面探讨ASP.NET 2.0中的Web控件改进技术之概述(一) ASP.NET 2.0并没有抛弃1.1版本中的任何现有控件,而是增加了一组新的控件;同时还引入了若干新的控件开发技术.本系列文章将对这 ...
最新文章
- Java设计模式(七):适配器设计模式
- 关于可迭代对象、迭代器和生成器
- tomcat启动关闭两种方法
- Windows SharePoint Services To Be Open Source With 2007 Microsoft Office Release
- 哪三级分类java_技术汇总:第五章:使用angularjs做首页三级分类
- python限制输入长度_textFiled限制输入长度.
- “华尔街之狼”:预计BTC价格将反弹至10万美元
- oracle取字段第三位字符,oracle截取字符串(截取某个字符前面的字符串)
- salesforce chatter提醒带Mention(即@)
- 微信公众号H5开发,实现网页授权(静默登录)
- PHP 毫秒级时间戳生成
- echarts网络拓扑图动态流程图
- CoinGeek直播大会(2020)将在著名的纽约曼哈顿中心举行
- L1-079 天梯赛的善良 (20 分)python
- KDJ金叉死叉分析以及KDJ金叉的买点形态
- 3.4. Transactions
- 粗放时代到规范时代,爬虫该何去何从?
- 10.31纪中DAY3_公牛和母牛 气象牛 轻轨 设计
- Java中Scanner类的close()方法所引发的错误
- php表单验证_用PHP进行表单验证
热门文章
- bigdecimal 保留两位小数_Python的保留小数及对齐
- python find函数 和index的区别_使用带有find和index的map时Python2和Python3之间的区别...
- cesium 经纬度绘制点_炫酷大屏地图自定义绘制(一)
- mysql异常恢复工具_[MySQL异常恢复]mysql ibd文件恢复
- autojs 云控_autojs websocket 核心示例代码,云控技术
- python函数可变长参数_day14 Python函数之可变长参数
- 电脑打字手指正确姿势_正确的弹琴手型,应该是怎样的?
- 页面错误!请稍后再试_微信内嵌H5页面授权和分享
- docker linux 快速开窗口_Linux搭建docker环境并简单实用
- oracle定义变量sql赋值_ORACLE获取SQL绑定变量值的方法总结