面向对象编程理论知识与思想(oop的思想与原则)

203 篇文章 4 订阅
108 篇文章 2 订阅

面向对象编程理论知识与思想(oop的思想与原则)

第一部分:oop理论基础

对象:对象是一个自包含的实体,用一组可识别的特性和行为来标识。
面向对象编程(Object-Oriented Programming,OOP)其实就是针对对象编程。
类:类就是具有相同的属性和功能的对象的抽象的集合。
第一,类名称首字母要大写。
第二,对外公开的方法需要用 "public"修饰符。
实例就是一个真实的对象。实例化就是创建对象的过程,使用new关键字创建。
构造方法,又叫构造函数,其实就是对类进行初始化。构造方法与类同名,无返回值,也不需要void,在new时候调用。
所有类都有构造方法,如果你不编码则系统默认生成空的构造方法,若你有定义自己的构造方法,那么默认的构造方法就会失效。
方法重载提供了创建同名的多个方法的能力,但这些方法需要使用不同的参数类型。
方法重载时,两个方法必须要方法名相同,但参数类型或个数必须要有所不同。方法重载可在不改变原方法的基础上,新增功能。

属性成字段:属性是一个方法或一对方法,但在调用它的代码看来,它是一个字段,即属性适合于以字段的地方使用方法调用的场合。字段是存储类要满足其设计所需要的数据,字段是与类相关的变量。通常属性是公有的,字段是私有的。
属性有两个方法get和set,只有get时表示是只读属性。

修饰符:
public 表示它所修饰的类成员可以允许其它任何类来访问,俗称公有的。
private 表示只允许同一个类中的成员访问,其它类包括它的字类无法访问,俗称私有的。
protected 表示继承时子类可以对基类有完全访问权,即对子类公开,但不对其它类公开。

封装:每个对象都包含它能进行操作所需要的所有信息,这个特性称为封装。因此对象不必依赖其它对象来完成自己的操作。
封装的好处:
第一,良好的封装能减少耦合
第二,类内部的实现可以自由地修改
第三,类具有清晰的对外接口

继承:对象的继承代表了一种'is-a'的关系。如果两个对象A和B,可以描述为'B是A‘,则表明B可以继承A。
继承者还可以理解为是对被继承者的特殊化,因为它除了具备继承者的特性殩,还具备自己独有的个性。
继承定义了类如何相互关联,共享特性。继承的工作方式是,定义父类和子类,或叫基类和派生类,其中子类继承父类的所有特性。子类不但继承了父类的所有特性,还可以定义新的特性。
学习继承最好是记住三句话:如果子类继承于父类,
第一,子类拥有父类非private的属性和功能
第二,子类具有自己的属性和功能,即子类可以扩展父类没有的属性和功能
第三,子类还可以以自己的方式实现父类的功能(方法重写)

子类从它的父类中继承的成员有方法,域,属性,事件,索引指示器,但对于构造方法,有一些特殊,不能被继承,只能被调用。对于调用父类的成员,可以用base关键字。
如:
class Cat : Animal
{
 public Cat() : base()
 {

 }
 public Cat(String name) : base(name)
 {
  
 }
 ...
}

不用继承的话,如果要修改功能,就必须在所有重复的方法中修改,代码越多,出错的可能性就越大,而继承的优点是,继承使得所有子类公共的部分都放在了父类,使得代码得到了共享,
就避免了重复,另外,继承可使得修改或扩展继承而来的实现都较为容易。

继承是有缺点的,那就是父类变,则子类不得不变。继承会破坏包装,父类实现细节暴露给子类。继承显然是一种类与类之间强耦合的关系。
当两个类之间具备'is-a'关系时,可以也才考虑继承。

多态:多态表示没的对象可以执行相同的动作,但要通过它们自己的实现代码来执行。

当表现为多态时,
第一,子类以父类的身份出现。(必须定义为父类)
第二,子类在工作时以自己的方式来实现 (通过重写父类的方法)
第三,子类以父类的身份出现时,子类特有的属性和方法不可以使用(除了重写的方法实现外,其它的只能和父类一样,子类的特性不可见)

为了使子类的实例完全接替来自父类的类成员,父类必须将该成员声明为虚拟的,这是通过在该成员的返回类型之前添加virtual关键字来实现(其它抽象方法,接口也可以实现多态)
子类可以选择使用override关键字,将父类实现替换为自己的实现。这就是方法重写 Override.或叫做方法覆写。

多态的原理是当方法被调用时,无论对象是否被转换为其父类,都只有位于对象继承最末端的方法实现被调用。也就是说,虚方法是按照其运行时类型而非编译时类型进行动态调用的。

抽象类:
c#允许把类和方法声明为abstract,即抽象类和抽象方法
抽象类需要注意几点:
第一,抽象类不能实例化
第二,抽象方法是必须被子类重写的方法
第三,如果类中包含抽象方法,那么类类必须定义为抽象类,不论是否还包含其它一般方法。
设计抽象类时尽可能让它拥有多的共同代码,拥有尽可能少的数据。
抽象类通常代表一个抽象概念,它提供一个继承的出发点,当设计一个新的抽象类时,一定是用来继承的,所以,在一个以继承关系形成的等级结构里面,树叶节点应当是具体类,而树枝节点均应当是抽象类。

接口:interface,接口是把隐式公共方法和属性组合起来,以封装特定功能的一个集合。一旦类实现了接口,类就可以支持接口所指定的所有的属性和成员。声明接口在语法上与抽象类完全相同,但不允许提供接口中任何成员的执行方式。实现接口的类就类就必须实现接口中的所有的方法和属性。
一个类可以支持多个接口,多个类也可以支持相同的接口。

接口用interface声明,而不是class,接口名称前要加'I',接口中的方法和属性前面不能有修饰符,方法没有方法体。(接口的命名,前面要加一个大写的字母’I‘,这是规范。)

抽象类与接口的区别:
从表象上来说,抽象类可以给出一些成员的实现,而接口不能包含成员的实现。抽象类的抽象成员可以被子类部分实现,接口成员需要全部实现。一个类只能继承一个抽象类,但可以实现多个接口。另:
第一,类是对对象的抽象,抽象类是对类的抽象,接口是对行为的抽象。
第二,如果行为跨越不同类的对象,可使用接口,对于一些相似的类对象,用继承抽象类。(或者可以理解为抽象类是纵向的,而接口是横向的)
第三,从设计角度来讲,抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类。而接口是根本不知子类的存在,方法如何实现还不确定,预先定义。

接口可以理解为是一组行为的规范的集合,实现它的类都必须严格遵守。实现类与接口之间并无明显的包含或拥有关系。而抽象类与实现类之间是继承关系。还是'is-a' 的关系。

实现接口与继承类并不冲突,一个类可以同时继承类,同时实现接口。

第二部分:oop思想遵循的一些原则与设计思想

编程原则一 尽量避免重复代码;有重复的代码就要考虑把它抽象出来并封装之。

面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同的属性功和功能的对象的抽象集合才是类;

面向对象设计其实就是希望做到代码的责任分解。

对象的继承关系是在编译时就定义好了,所以无法在运行时改变从父类继承的实现,子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化,当你需要复用子类时,如果继承下来的实现不适合解决新问题,则父类必须重写或被其它更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。

面向对象设计模式体现的就是抽象的思想,类是什么,类是对对象的抽象,抽象类呢,其实就是对类的抽象,那接口呢,说白了就是对行为的抽象。


---依赖倒转原则---
依赖倒转原则:抽象不应该依赖细节,细节应该依赖于抽象。说白了就是要针对接口编程,不要对实现编程。
高层模块不应该依赖低层模块,两个都应该依赖于抽象。

---里氏代换原则---
里氏代换原则:一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序的行为没有变化,简单地说,子类型必须能够替换掉它们的父类型。

---依赖倒转---
依赖倒转其实可以说是面向对象设计的标志,用哪种语言编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象编程,反之就是过程化的设计。

---开放-封闭原则---
开放-封闭原则,是说软件实体(类,模块,函数等)应该可以扩展,但是不可以修改[ASD];即对扩展开放(Open for extension),对更改封闭(Closed for modification)

面对需求,对程序的改动是通过增加新代码来进行的,而不是更改现有的代码,这就是开放-封闭原则的精神所在。
遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护,可扩展,可复用,灵活性好。

---单一职责原则---
单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因;
如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其它职责的能力,这种会导致脆弱的设计,就变化发生时,设计会遭受到意想不到的破坏;
软件设计真正要做的许多内容,就是发现职责就把那些职责相互分离,如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责,就要考虑职责分离;

---迪米特法则---
迪米特法则(LoD),也叫最少知识原则。如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

迪米特法则首先强调的前提是在类的结构设计上,每一个类都应当尽量降低成员的访问权限,也就是说,一个类包装好自己的private状态,不需要让别的类知道的字段或行为就不要公开。
迪米特法则其根本思想是强调了类之间的松耦合。类之间的耦合越弱,越利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。

---合成/聚合复用原则---
合成/聚合复用原则(CARP),尽量使用合成/聚合,尽量不要使用类继承。
聚合表示一种弱的‘拥有’关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;合成则是一种强的‘拥有’关系,体现了严格的部分与整体的关系,部分与整体的生命周期一样。

聚合合成关系图1:


合成/聚合复用原则的好处是,优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上,这样类和类继承层次会保持较小规模,并且不大可能为不可控制的宠然大物。

附:类的继承关系结构图:

 

声明:本文大部分内容摘录于大话设计模式;


 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值