C# 面向对象之概念理解(2)
委托
如果对象A为了满足某个请求,而寻求另一个对象B的帮助,这被称作是A对B的委托。
对象间的委托,和现实世界中人与人之间的委托一样:如果你“那位”要求你在他外出公干期间帮忙助剪草坪,而你转而雇佣邻居小孩干活,只要他不偷懒,则草坪就不会疯长。
对象之间发生委托,同样也不会为消息发出者所知。
对象的访问
- 对象A向对象B传递消息的唯一途径,是A能访问B的句柄。有以下几可能:
- 对象A可能把对象B的引用当作一个attribute维护;
- 对象B作为一个参数传递到A的一个方法;
- 对象B的引用,可能对于整个应用程序是“全局引用”;
- 对象A可以调用第三个对象C,明确地要求或得到B的引用。
引用变量有时被非正式地看做“抓住了”对象,所以我们常使用非正式术语句柄作类似这样的表达。
如果对象A是对象B的客户,则对象B就被认为是A的服务供应者。
封装
表示将对象状态和行为绑到单一逻辑单元中的机制。
- 避免对封装数据未经授权访问。
- 帮助确保数据完整。
- 当私有特征改变时限制连锁反应。
- 在类的自身方法中使用访问器
信息隐藏是一种强大的机制,它保护对象数据的完整性,也能在应用程序的私有实现细节被不可避免地修改时防止客户代码出现连锁反应。
对象间关系:
类与类之间结构关系的正式名称是“关联”。关联是指类间关系,术语“链接”则是指两个特定对象(实体)间的结构关系。
关联与链接不同:
- 关联是某个类/类型的对象间可能存在的关系;
- 链接是这些特定类型的对象间实际存在的关系。
换言之,关联让链接称为可能。
定义两个不同类之间的关联关系,称为二元关联。
相同类的两个实体间的关系,称为反身关联。
结构关系
一对一(1:1);
一对多(1:m)
多对多(m:m)
注意,结对关系的概念只是用与关联,不适用于链接。
聚合
聚合:是一种特殊形式的关联,它指明“包括”、“由……构成”或“有……”的关系。和关联一样,聚合用于描述类A和类B之间的关系,不同的是,我们可以用聚合表述更多种关系:某对象属于类A,类A就是聚合类,类A包括一些类型为B的组件对象,或由一些类型为B的组件对象聚合而成。含有“包括”、“由……组成”等短语来命名这种关系,则该关系极有可能是一种聚合关系。
继承
继承常常指出两个类之间的“A是B”关系,因为如果类B派生自类A,则B则是A的一种特例。基类具有的特点对于其派生类都适用。
继承相关术语:
- 特殊化:被用来指称从一个类派生新类的过程。
- 普遍化:则用来指称相反过程:从几个现存类中找出共性,为它们创造一个新的共同基类。
层次结构
- 把层次结构中每个类称作一个节点;
- 任意一个节点被看作(直接或间接地)派生自该层次结构中它上方的节点,这些节点总括起来称作它的祖先;
- 如果一个祖先节点刚好在紧邻指定节点的上方,则被看做指定节点的直接基类;
- 层次结构中位于给定节点下发的所有节点被称作它的子孙;
- 层次结构顶端的节点被称作根节点;
- 一个末梢、一片叶子或节点,是指没有后代的节点;
- 派生自同一个直接基类的节点是兄弟。
继承真的是一种类间关系吗?
关联、聚合和继承都被称作是类间关系。继承与关联、聚合在对象层级上有所区别。
关联(和作为特殊关联的聚合)可以看作依靠相关类之间的现存关联把独立的对象联系起来,与之不同,继承是描述单个对象特征的一种方式。在继承的情形中,对象同时也是派生类和该派生类的所有基类的实体。
层级结构中的所有类——A及其所有子类——都可以来创建根对象。
通过继承,一个对象可以拥有“多重身份”。例如:研究生(GraduateStudent)是学生(Student)也是人(Person)。
类的派生规则:所可为
- 可以通过添加特征来扩展基类。
- 可以特质话执行派生类,执行从其基类继承的一个或多个服务的操作方式(重写)。
派生类规则:当不为。
不应该改变特征的语义——即蕴含的目的、表达的意义。
- 不可改变特征语义
- 不可移除特征
- 不可修改返回(Property)类型
- 不可试图改变方法头
ps:这里从层次结构来看,确实和javaScript里的文档结构有点类似。不过理解时须知,为什么要继承?不单单是为了重用代码,还为了扩展基类的功能(既然是扩展,那么必然具有基类的功能)或重写基类的功能。还有一点:在非叶类已经在应用程序代码中被使用后,如非万不得已,应避免向其添加新特征,以防在整个类继承结构中导致连锁反应(封闭开发原则)。
多载
多载允许同一个类两个或多个不同方法拥有相同方法名和不同的参数签名。
多重继承
如果出于某种目的,需要把两个不同基类的要素融合到一起,创建一个混血类,就得使用多重继承。使用多重继承,类层次结构中的每个类都被允许拥有两个或多个直接祖先类。
表面看起来易如反掌,事实确是:C#语言不支持多重继承。
为什么不支持呢?
根源在于,如果这些基类:拥有同样的签名的方法,但方法体具体实现不同;拥有同样attribute(同样名称和同样类型);拥有同样attribute,但类型不同;在编译时就会造成重复:编译器没有办法知道应该移除哪一个或者继承哪一个,而我们不该移除任何一个(因为它们表达了不同的信息)。这就是OO编程语言实现多重继承之痛。Ps:说白了就是:编译器过不了,我们不放过,这也就是引出了抽象类,接口的出现(下节再说)。
C# 面向对象之概念理解(2)的更多相关文章
- C# 面向对象之概念理解
什么是对象? <韦氏大词典>中对对象定义: (1)某种可为人所感知的物质. (2)思维.感受或动作所作用的物质或精神体. ----说白了万物皆对象 熟悉的对象描述: 对象就是客观世界中的物 ...
- C# 面向对象之概念理解(3)
多态 多态是指两个或多个属于不同类的对象,对同一个消息(方法调用)做出不同响应的能力. 多态(<韦氏大词典>)中定义:可以呈现不同形式的能力或状态. C#如何实现多态的知识——即继承上覆载 ...
- JAVA_SE基础——22.面向对象的概念
我写博客是为了提升自己和为了进入黑马程序员学习,还有分享些自己的心得给大家,希望能帮助大家学习JAVA. 我是自学的,如果写的有错误或者能更好的修改的请提出. 在这里我先引用下<think in ...
- 我对面向对象设计的理解——Java接口和Java抽象类
在没有好好地研习面向对象设计的设计模式之前,我对Java接口和Java抽象类的认识还是很模糊,很不可理解. 刚学Java语言时,就很难理解为什么要有接口这个概念,虽说是可以实现所谓的多继承,可一个只有 ...
- OO 面向对象的概念
面向对象的概念 一.什么是面向对象? 传统的:世间万物都是对象.例如:桌子,凳子,电脑等: 个人理解: 1.软件开发方法: 2.面向对象是一种解决问题和分析问题的(编程)一种思想: 3.他是通过面向过 ...
- OC学习--面向对象的个人理解
1. 什么是面向对象? 以下一段话是我在百度上找的解释: 面向对象(Object Oriented,OO)是软件开发方法.面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统.交互式界面 ...
- 03.JavaScript 面向对象精要--理解对象
JavaScript 面向对象精要--理解对象 尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的对象.JavaScript中的对象是动态的. 一.定义属性 当一个属性第1次 ...
- JAVA类与对象(一)----基础概念理解
面向对象基本概念 面向对象是一种新兴的程序设计方法,或者说是一种新的程序设计规范,其基本思想是使用对象.类.继承.封装.消息等基本概念来进行程序设计.它是从现实世界客观存在的事物(即对象)出发来构造软 ...
- [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
javascript面向对象编程方式,对于初学者来说,会比较难懂. 要学会面向对象以及使用面向对象编程,理解对象的创建在内存中的表示,至关重要. 首先,我们来一段简单的对象创建代码 var obj = ...
随机推荐
- CICS&&XA
CICS (Customer Information Control System) 是IBM 公司的强大主机交易服务器.集成平台,在全球C.C++.COBOL等交易中间件市场上占有绝大多数客户.CI ...
- Linux系统环境变量及命令
Linux哪些我们常用,但是用的时候想不起来,这里做一个备忘录. Linux常用的变量: PATH 决定了shell将到哪些目录中寻找命令或程序 HOME 当前用户主目录 HISTSIZE 历史记录数 ...
- Abstract_Factory
#include <iostream> using namespace std; #define DESTORY_POINTER(ptr) if (ptr) { delete ptr; p ...
- Javascript this 解析
Javascript中,this是一个非常有用的关键字, this是在运行时基于函数的运行环境绑定的,但是,如果使用的时候不注意,很容易就出错了. ECMAScript Standard对this的定 ...
- .Net 将一个DataTable分解成多个DataTable
这两天遇到一个问题,我们所接触 的一个系统在导出数据到Excel的时候,产生了内存溢出的错误.原因在于数据过大,它导出是将所有数据存放在一个DataSet的一个表中,再将这个数 据集放入session ...
- 方法的可变长参数 传入参数个数不确定可用(Type ... values)
/** * 可变长的参数. * 有时候,我们传入到方法的参数的个数是不固定的,为了解决这个问题,我们一般采用下面的方法: * 1. 重载,多重载几个方法,尽可能的满足参数的个数.显然这不是什么好办法. ...
- 一个好用的PHP验证码类
分享一个好用的php验证码类,包括调用示例. 说明: 如果不适用指定的字体,那么就用imagestring()函数,如果需要遇到指定的字体,就要用到imagettftext()函数.字体的位置在C盘下 ...
- 使用另一种方式实现js中Function的调用(call/apply/bind)
在JavaScript中函数的调用可以有多种方式,但更经典的莫过于call和apply.call跟apply都绑定在函数上,他们两个的第一个参数意义相同,传入一个对象,他作为函数的执行环境(实质上是为 ...
- ORACLE 11G R2 修改"用户名"
SQL> create pfile from spfile; 修改pfile文件,添加隐含参数 *._enable_rename_user='TRUE',将数据库以restrict方式启动 1. ...
- Spring中@Transactional事务回滚实例及源码
一.使用场景举例 在了解@Transactional怎么用之前我们必须要先知道@Transactional有什么用.下面举个栗子:比如一个部门里面有很多成员,这两者分别保存在部门表和成员表里面,在删除 ...