面向对象的重新思考

在刚开始学习一门面向对象语言的时候,我们是这样写代码的:

我们会先写一个小狗类,然后new它,最后调用它的方法实现功能。

例如:

Dog d=new Dog();//造个小狗

d.shout();//小狗看到stranger会叫

看得懂这段代码,说明你的面向过程语言基础学的不错~~~~~

好的,这段代码先到这里,我们先来谈谈面向对象的特征:

1,抽象:

首先想想我们在什么时候用到抽象?

a.当我在设计一个系统的时候,我需要把一些东西归类,比如,小狗,小猫,这些都会做一个animal类,然后让小狗小猫继承这个animal.这是基本的类抽象

b.还有一类抽象,比如我们写个接口,让一个类去实现这个接口,这是接口的抽象;(抽象类的抽象和接口的抽象是一样的,都没有方法体,都要子类去具体实现);

c.类的成员变量使用超类或接口:

当某个类作为另一个类C的成员变量的时候,而这个子类又有诸多变化,这时我们就要考虑将这个变化的部分做成多个子类,并且将这多个子类抽象出来一个父类,将这个父类作为类C 的成员变量。

比如,我现在有个很多收费策略,然后在类C中有一个要调用计算收费的方法,但是因为调用时的诸多情况,我必须在调用时动态确定使用哪种收费策略,所以,在定义这个C的成员变量时,我们就要使用抽象出来的父类了,即为众多的策略定义一个父类或接口。

这时情况又和上面的小猫小狗的情况一样了。而且预先设计中的抽象和重构方法时的抽象目的是相同的,都是为了系统的扩展性,易修改。

总的来看,抽象起到了一个概括的作用,就像拿着一条摸起来凉凉的,张的长长的,吐着舌头的东西问你,知道这是什么吗?你不确定这是哪种蛇,但是,你会非常肯定的回答:这是条蛇!这样的回答虽然不准确,但是却给了你百度的时间,等你百度过后,你就可以说:这是条@#[email protected]#蛇。。。。

2,封装

封装能带来什么好处呢:

1,首先,想想你使用过的实体类,你能很快写出这个是学生的ID,这个是教师的ID。。。这里,封装实体的数据,起到了一个打包的作用,将属性绑定到了类上,方便查找和使用,上面列举的是对于属性的封装。类中也有方法啊,所以,同样,也有方法的封装。

2,回想设计模式,有些对象的创建过程我们是无需参与的:例如,在单例模式中,我们将类之创建一个实例的过程交给类本身来处理,将类的创建封装在了类里面,避免了创建多个实例; 还有我们熟悉的各种工厂模式,我们将对象的创建迁移到了具体的工厂类里面,去除了选择问题。

3,对类行为的封装

回想一下命令模式,我们把各个命令做成类,将请求操作的对象和执行操作的对象分开了,接触了这里的紧耦合。

3,继承

在面向对象的设计中,我们是免不了使用继承的,首先,来看一下公认的使用继承带来的那些好处:

a.基本好处:

可以继承父类的属性和方法,获得父类的行为。例如,我们在使用模板方法的时候,将重复的东西都放到父类,子类只需在继承父类的基础上做一个很小的变更就ok了。

b.通过继承达到“类型匹配”

在装饰者模式中,我们让服饰类去继承people,这在现实中是不可理喻的,但是在设计中,正是通过这个继承,让我们可以在形象展示中层层调用父类的方法,达到一个装饰的效果。感觉这个模式设计的非常酷!!!

但是,继承的后果你想过吗?

1,多继承的后果:C++强大的多继承为代码的复用提供了很大的方便,但是也带来了很多问题,比如多继承的二义性问题,还有继承关系的混乱问题;

2,为了复用而使用的继承会给维护增加的子类带来困难,因为子类很可能不具有它从父类继承的方法,而且它也无法屏蔽从父类里面继承的方法。就像是富二代老爸想给儿子安排接手自己公司可是儿子却偏偏想去玩儿音乐。如果子类不需要父类的方法或者根本不能去实现父类的方法,这就让继承关系带来了一个非常尴尬的事情。

面对继承可能带来的后遗症,所以,我们才才有了后来的提倡使用组合取代继承。

4,多态

如果说面向对象为什么可扩展性这么强,而且非常灵活的原因,感觉多态起了很大的作用。

首先,回到我们开始的小狗的问题上:

Dog d=new Dog();//造个小狗

d.shout();//小狗看到stranger会叫

如果有一天,我不想听小狗叫了,我想听猫叫了,这时,可能我们会这样写:

//Dog d=new Dog();//造个小狗

//d.shout();//小狗看到stranger会叫

Cat c=new Cat();

c.shout();

但是,过了两天,我又想听鸡叫了,这时,你可能又把小猫的代码注释掉,改成鸡叫的代码,但是,作为一个程序员,你要认识到,一段相似的代码写到第三遍了,那么一定是设计的有问题。

这时,多态的作用就显示出来,这也是为什么在编程中一直强调的写法:将父类的引用指向子类的对象。

如果我们使用了这种写法:

Animala=new Cat();

a.shout();

那么,我们日后的变更将更加方便,当我们要变更具体的实现的时候,只要稍加改动就好啦!

另外,还有重写,重载等多态的表现,但是还是觉得上面的最经典。

PS:最近在学习Java+Head first,感觉这是我真正迈入面向对象大门的开始~~~

时间: 2024-11-08 22:04:11

面向对象的重新思考的相关文章

关于面向对象的一些思考

适才在写python程序,写一个对象的集合容器类,纠结要不要实现迭代器方法来允许for in语句.突然发现,for a in obj和for a in obj.l 给人很大的不同感.我并没有一下子得到明确的思绪(这也不构成问题,仅仅是一个"问题"),想到在哲学群里的争论和一些以前的思考,决定写一篇博客. 其实写到这里,我已经有些思路了,那就是python不隐藏属性,做不到很好的封装--不过更多地,我也没有刻意区分过"状态"和"属性"(也许&quo

day05面向对象

1 面向对象 1.1 万物皆对象 我们是怎么认识世界的? 人类从小就不断的接触到各种各类存在世界上的各种生物,然后通过事物的公共特性,将它们归类,所以以后就不会出现见到猫叫老虎.那么我们在现实生活中,是通过具体的某个事物归纳总结它们的公共特性然后产生类那么类就描述了该种事物的的共别.性,相当于造事物的图纸,我们可以根据这个图纸去做出具体的实体对象. 对象:在现实生活中存在具体的一个事物.; 类:实际就是对某种类型事物的共性属性与行为的抽取. 人类认识世界: 对象----à类. 在java中:  

JavaSE——面向对象与面向过程、类与对象、(属性、方法、构造器)等

一:面向对象与面向过程 二者都是一种思想,面向对象是相对于面向过程而言的. 面向过程: 1.面向过程思想强调的是过程(动作). 2.在面向过程的开发中,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然而由这些功能方法相互调用,完成需求. 3.面向过程的典型代表语言是:C语言. 面向对象: 1.把步骤和方法封装起来,根据不同的功能,进行不同的封装,用的时候,找到对应的类就可以了. 2.将功能封装进对象,强调具备了功能的对象.这就是面向对象的思想.典型的语言是:C++,Java. 3

三、JAVA面向对象

1.面向过程的设计思想和面向对象的设计思想(例如:我要去新疆) ---面向过程:我开车,我挂挡,我踩油门,我过河北...... ---面向对象:我命令车去新疆,车怎么去不关我事(信息封装在车这个类的内部,我不用了解车整个开动的过程) 2.类是用于描述同一类型的对象的一个抽象的概念,类定义了这一类对象所因具有的静态和动态属性. ---类可以看成一类对象的模版,对象可以看成该类的一个具体实例. 3.类(对象)之间的关系 --- 关联关系 --- 继承关系(一般和特殊) --- 聚合关系(整体和部分)

[WuDe]C#程序设计教程 - 第2章 C#面向对象基础

第2章 C#面向对象基础 2.1 类 类是一种数据类型,而对象是具有这种类型的变量 [类的修饰符] class 类名 [:基类名] { //类的成员 }[;] 访问级别的用处在于控制成员在哪些地方可以被访问,这样达到面向对象中"封装"的目的;控制对外访问权限 在类这个级别,不写访问修饰符默认为internal,类只有两个访问修饰符,public 和internal (暂时这样理解),在类里面,方法外定义变量或方法前不加访问修饰符,默认为private Public公共类:不受限制对该类

看Java中==、equals、hashCode的来龙去脉

我有一个哥们去参加了面试,面试官这样问一个Java问题: 你说一下java对象的equals方法调用什么方法呢?我这个哥们想了想,回答说"应该是比较的引用".听了这个答案之后,那个面试官摇头晃脑的说:"不对,你回答的不对,equals方法调用的是hashCode方法".于是乎,我那个技术还不错的哥们就悲壮地栽在这道题目上了. 今天晚上,西安历史上少有的热,那就好好总结一下这个题目的来龙去脉好了,也方便给后面的朋友们提个醒,不要栽在这么简单的问题上.你说这个面试官回答

C#语言-04.OOP基础

a. OOP:面对对象思想 i. 类:是一种功能强大的数据类型,而且是面向对象的基础 1. 语法:访问修饰符 class 类名{ //类的主体 } 2. 成员变量:不以"函数"形式体现 a. 常量:代表与类相关的常量值 b. 变量:类中的变量 c. 事件:由类产生的通知,用于说明发生了什么事件 d. 类型:属于类的局部类型 3. 成员函数:以"函数"形式体现 a. 方法:完成类中各种计算或功能的操作,不能和类同名.不能和类中其他成员同名 b. 属性:定义类的值,并对

初识继承和多态

集成的概念 在C#中,一个类可以继承另一个类,被继承的类通常称为父类或基类.继承其他类的类被称为子类或派生类.派生类的定义可以增加新的数据和功能,派生类的实例也直接可以使用父类的数据或功能,但父类的实例不可以直接使用子类定义的数据或功能 继承是面向对象编程中的一个重要特性.继承关系在类图中表示一个箭头,箭头指向父类如图所示: base关键字和protected修饰符 我们知道this关键字可以表示当前类的实例,通过它可以访问类本身的成员,在C#中还有一个base关键字表示父类,它可以用于访问父类

黑马程序员java-交通灯管理系统《十》

                   --Java培训.Android培训.iOS培训..Net培训.期待与您交流! -- 1,交通灯管理系统原理与分析 首先明白它的工作原理,由于刚刚学车,大概明白交通灯是如何运作的,一般来说车右转是默认不用看灯的,可以直接右转的, 但有时候当交通有箭头显示的时候又不一样了,所以我们不考虑这种情况.那么默认右转灯是一直绿的.根据东南西北四个方向 的车都有各自的三种路线,按道理,东南西北四个方向都有各自的三个方向的交通灯.从车方面考虑就有12(3x4)种路线,而