封装
封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。被封装的对象通常被成为抽象数据类型
封装的意义在于保护或者防止代码(数据)被我们无意中破坏
封装既可以封装成员变量,也可以封装成员方法
封装可以把程序按某种规则分成很多“块”,块与块之间可能会有联系,每个块都有一个可变部分和一个稳定的部分,我们需要把可变的部分和稳定的部分分离出来,将稳定的部分暴露给其他块,而将可变的部分隐藏起来,以便于随时可以让它修改,这项工作就是封装
例如:在用类实现某个逻辑的时候,类就是以上所说的块,实现功能的具体代码就是可变的部分,而public的方法或者属性就是稳定的部分
封装的意义:
封装的意义就是在于保护防止代码(数据)被我们无意中破坏,在面向对象程序设计中,数据被看做是一个中心的元素并且它不被其他的函数意外的修改。
封装提供了一个有效的途径来保护数据不被意外的破坏,相比我们将数据(用域来实现)在程序中定义为公用的(public)我们将它们(fields)(字段)定义为私有的(private)在很多方面会更好。
私有的数据可以用它两种方式来间接的控制,下面我们来看一些例子来学习者两种方法用以封装数据。第一种:我们用传统的存、取方法。第二种:我们用属性(property),无论我们使用那种的方法,我们的目标是在使用数据的同时不能使他受到任何的破坏和改变,有如下好处,
其一:使用者只需要了解如何通过类的接口使用类,而不用关心类的内部数据结构和数据组织方法。
其二:高内聚,低耦合一直是我们所追求的,用好封装恰恰可以减少耦合
其三:只要对外结构不改变,可以任意修改内部实现,这个可以很好的对应变化
其四:类具有了简介清晰的对外结构,降低了使用者的学习过程
因为在class中的方法中,所以会在栈中
如果说提前直接声明的属性,就是在堆中
向上转型:只能访问父类型成员
声明父类型引用,指向子类型对象
比如:Person p3 = new Student();
可以访问什么成员取决于声明时的类型
如果需要访问子类成员,通过as访问子类型对象
Student s4 = p3 as Student
这里的话,栈中多了一个地址,但是堆中的子类型对象是一样的
P3和s4存储的引用相同
隔离,调用,定义
三大特征: 封装继承多态:
封装:
也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏,封装是面向对象的特征之一,是对象和类概念的主要特性。简单的说,一个类就是封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
封装的好处:
良好的封装能减少耦合
类内部实现就可以自由的修改
类具有清晰的接口
所谓继承:
是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力。它可以使用现有类的所有功能,并在无需重新编写原来类的情况下对这些功能进行扩展。通过继承创建的新类成为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程,要实现继承,可以通过“继承”和“组合”来实现。继承概念的实现方式有两类:实现继承与接口继承。实现继承是值直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。
所谓多态:
就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,单通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。
五大基本原则:
单一职责原则SRP:
是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的功能不能太多,否则一天到晚虽然忙忙碌碌但是效率却高不起来。
开放封闭原则OCP:
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来指服务端功能,而现在要加入客户端功能,那么应该当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来
里氏替换原则 LSP:
子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年会,所有员工可以参加抽奖,无论是总部员工还是外派员工,都应当可以参加抽奖,否则这个公司就不和谐了。
依赖倒置原则:DIP:
具体依赖抽象,上层依赖下层,假设B是较A低的模块,但是B需要使用到A的功能,这个时候,B应当直接使用A中的具体类:而应当由B定义一首相结构,并由A来实现这个抽象接口。B只使用这个抽象接口,并由A来实现这个抽象接口,B值使用这个抽象接口。通过上层模块难以避免依赖下层模块,加入B也直接依赖A的实现,那么就可能造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的CPP文件,而编译B时同样要直接包含到A的CPP文件。
接口分离原则ISP:
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来。
迪米特法则:
又叫做最少知识原则LKP,
就是说一个对象应当对其他对象有尽可能少的了解,不和陌生人说话,对于面向OOD来说,又被解释为下面几种方式:一个软件试题应当尽可能少的与其他试题发生相互作用,每个软件单位对其他的单位都只有最少的知识。而且局限于哪些与本单位密切相关的软件单位,迪米特法则的初衷是减低类之间的耦合因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系
未完待续