面向对象编程是int什么意思啊

简单理解PHP的面向对象编程方式 - ThinkPHP框架
PHP尽管只被设计于运行在服务器软件上,但仍然包含很多面向对象的要素,比如类和方法,本文就带初学者来简单理解PHP的面向对象编程方式.
与大多数可以面向对象的编程语言不一样,&PHP&是同时支持面向过程和面向对象的编程方式,&PHP&开发者可以在面向过程和面向对象二者中自由选择其一或是混合使用,不过由于在&PHP5&之前的版本中,&PHP&主要还是面向过程的编程语言,因此大多时候&PHP&开发者应该还是选择面向过程的方式进行开发,事实上,&Kayo&认为即使一个&PHP&开发者完全不使用面向对象,他也能开发出很出色的&PHP&程序,我们可以想象,&Web&页面的解析本身就很过程化,在&HTML&中嵌入面向过程处理的代码是非常自然的手段,因此不能说面向对象是一种比面向过程更加优秀的编程方式,只是另一种编程选择,当然这里说的是&PHP&中的情况。
对于&PHP&中面向过程和面向对象各自的优缺点,相信在网上稍查一下就会很清楚了,面向过程开发周期短,发布快,效率较高,面向对象开发周期长,效率较低但易于维护,改进,扩展和开发&API&。显然易见,我们很难说哪一个方式会更优秀,与其争论哪一种编程方式更优秀,不如尽量发挥出两种编程方式各自的优势。
回到&PHP&的面向对象编程,在使用面向对象的过程中还是很容易就感受到它的优势,最明显的地方是代码功能更加清晰,数据处理,用户登陆,内容呈现等各写成一个类,在页面中只需包含这些类、实例化对象,然后再用简洁的语句应用对象就行,这与面向过程中把数据处理,用户登陆,还有内容等部分写在一起相比,前者的编程思路肯定更加清晰和易于理解,相信团队开发中应该更为偏向于面向对象编程。
下面举一个简单的例子说明一下面向过程和面向对象两种方式各自的优缺点
在处理表单或接受&url&参数时,为了防止&SQL&注入等问题,&PHP&开发者常常需要过滤字符串。
在面向过程的方式中,我们会在需要过滤字符串的语句中调用各种过滤字符串的库函数或自定义函数,这样下来,页面中就会出现很多不同的过滤函数甚至还有复杂的正则表达式,即使在页面中写了足够的注释难免还是比较混乱,下面看看面向对象的处理方式。
首先是定义了一个简单的处理字符串的类,把各种复杂的字符串处理写成方法(关于&PHP&面向对象的知识可以&Google&,本文不另外叙述。)&&&&
/*&字符串处理类
&*&参数$length用作判断字符串是否超过指定长度
&*&转义&SQL&语句中使用的字符串中的特殊字符
&*&正则限制字符串内只能为数字
&*&判断字符串是否为空
&*&判断字符串长度
//&创建字符串处理类
class&StringFiltration&{
&&//&构造方法
&&function&__construct($the_length&=&NULL){
&&&&$this-&length&=&$the_
&&//&转义&SQL&语句中使用的字符串中的特殊字符
&&function&realEscapeString($the_string){
&&&&return&mysql_real_escape_string($the_string);
&&//&正则限制字符串内只能为数字
&&function&eregNumber($the_string){
&&&&if(&ereg(&^[0-9]+$&,$the_string)&)
&&&&&&return&
&&&&&&return&
&&//&判断字符串是否为空
&&function&strlenString($the_string){
&&&&return&strlen($the_string);
&&//&判断字符串长度
&&function&ifOverStrlenLength($the_string){
&&&&if(&strlen($the_string)&&&$this-&length&)
&&&&&&return&
&&&&&&return&
然后在需要过滤字符串的页面中实例化该类
$string&=&new&StringFiltration();&
接着在过滤或判断字符串时调用类中定义好的方法,于是页面中会出现一些调用方法的语句。&&&&
$email&=&$string-&realEscapeString($_POST['email']);
$postId&=&$string-&eregNumber($id);
在上面的例子中,我们可以看到,在面向对象处理字符串之前,我们必须定义一个类,然后再在需要的页面中实例化这个类并调用这个类中的方法,这里看来,面向对象的效率相比面向过程是低了,而且也很麻烦,不过这样的优势也很明显,实际处理或判断字符串的语句都写在类的内部,在调用方法的页面并不会出现各种复杂的自定义函数和诸如正则表达式这样复杂的语句,页面的结构乃至整个网站的结构更加清晰了,并且在写好一个类后,日后进行&PHP&开发时都可以再使用这个类,从长远来看效率反而高了。因此一直都在进行&PHP&面向过程编程的开发者不妨换种思路,试试面向对象。
积分:3986
ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。我是怎样教媳妇面向对象编程的 - 技术翻译 - 开源中国社区
我是怎样教媳妇面向对象编程的
【已翻译100%】
英文原文:
推荐于 5年前 (共 33 段, 翻译完成于 01-09)
参与翻译&(9人)&: ,
我老婆 Farhana 想要继续软件开发生涯(之前因为我们的第一个孩子出生,她不得不放弃)。我已经有了一些软件设计和开发的经验,所以这几天我就在试着帮助她学习OOD。
由于我早年在软件开发的经验,我总是发现无论一个技术问题看上去多么难搞,只要从现实生活的角度去解释或用对话的方式去讨论总能让它变得更简单。关于OOD,我们已经有了许多成果丰硕的讨论,我觉得有人可能发现这是一个学习OOD有趣的方式,所以我想我应该分享出来。
&翻译得不错哦!
下面是我们的谈话步骤:
话题:介绍面向对象设计
丈夫:亲爱的,让我们开始学习面向对象设计。你了解面向对象规范,对吗?
妻子:你是指封装,继承和多态吗?是的,我了解这些规范。
丈夫:行,我想你已经知道怎么用类和对象了。今天我们来学习面向对象设计。
妻子:等等。了解面向对象规范对面向对象编程来说难道不够吗?我的意思是,我能够定义类,封装属性和方法。我能够根据它们的关系定义类的继承。那还有什么呢?
丈夫:很好的问题。面向对象规范和面向对象编程完全是两码事。让我展示一个现实生活中的例子来帮助你理解它们。
&翻译得不错哦!
我们从牙牙学语起,都是先从字母表学起的,对吧?
妻子: 嗯。
丈夫: 好,然后你就能认单词了,还能通过不同的字母拼写出不同的单词来。慢慢的,你能通过一些基本的语法把这些单词串成一句话。为了使句子时态正确且没有语病,你需要用一些介词,连词,等等。。看下面这句话
"I" (代词) "want" (动词) "to" (介词) "learn" (动词) "OOD" (名词)
通过把几个单词摆放妥当一句话就好了,然后用个关键词来说明一下这句话的重点。
&翻译得不错哦!
妻子: 亲爱的,你闲扯这些到底要说明什么呢
丈夫: 我说的这个例子跟面向对象规范很类似,面向对象规范为面向对象编程定义了基本的规范,它是面向对象编程的主要思想。面向对象规范好比基本的英语语法,这些语法教会了你怎么用一个个单词拼凑出一句句话来,而面向对象规范教你怎么用类,怎么把一些属性和方法封装在一个类里,怎么串出类之间的继承关系。
妻子: 啊哈,我知道了,那么,面向对象适用于哪里呢。
丈夫: 听我慢慢道来。现在,假设你想写点有内容有题材的文章。你当然还希望写点你比较擅长的题材的书,就会简单造几个句子是远远不够的,对吧。你需要笔耕不辍写出一些长篇大论,你还需要学习怎么可以让读者很容易就看懂你写的这些长篇大论。。。
&翻译得不错哦!
妻子:嗯,有那么点意思。。。继续吧
丈夫:现在,假如你想写本关于面向对象设计的书,你需要把这个大的课题拆分成一些小题目。把这些小题目分几个章节写,还得写前言,简介,说明,举例,一篇里还有很多段落。你需要设计一整本书,还得练习一些写作技巧,让文章读起来浅显易懂。这就是综观全局。
在软件开发中,OOD就是用来解决从全局出发考虑问题,在设计软件的时候,类和代码可以模块化,可重复使用,可灵活应用,现在已经有很多前人总结出的类和对象的设计原理了,我们直接拿来用就行了,总之,历史的车轮已经碾压出一条清晰的车轮印,我们只要照着走就可以了。
妻子: 哎,懂了点皮毛,还有很多要学呢。
丈夫:不用担心,你很快就会上手的,让我们接着来吧。
&翻译得不错哦!
话题:为什么要进行面向对象设计?
作者:有个很重要的问题,既然我们能够很快的创建几个类,编写程序并提交,为什么我们还要关注面向对象设计?这样不够么?
妻子:恩,以前我不知道面向对象设计,我也能开发提交项目。有什么关系?
丈夫:好吧,先让我给你看一个经典的引述:
"需求不变的程序开发会同行走在冰上一样简单。"
妻子:你是指软件开发说明书会被不断修改?
丈夫:非常正确!软件开发唯一的真理是“软件必然修改”。为什么?
&翻译得不错哦!
要知道,你的软件解决的是现实世界中的问题,而现实生活不是一成不变的。
可能你的软件现在运行良好。但它能灵活的支持“变化”吗?如果不能,那它就不是一个敏捷设计的软件。
妻子:好,那你就解释一下什么叫做“敏捷设计的软件”!
丈夫:“一个敏捷设计的软件能轻松应对变化,能被扩展和复用。”
而应用“面向对象设计”是做到敏捷设计的关键。那么,什么时候你可以说你的程序应用了面向对象设计?
&翻译得不错哦!
妻子:我也正想问呢。
丈夫:如果代码符合以下几点,那么你就在“面向对象设计”:
变化的代价极小
无需改代码即可扩展
妻子:然后呢?
丈夫:不只我们。很多人也花了很多时间和精力思考这个问题上,他们尝试更好的进行“面向对象设计”,并为“面向对象设计”指出几条基本的原则(你可以用在你的“面向对象设计”中)。他们也确实总结出了一些通用的设计模式(基于基本的原则)。
&翻译得不错哦!
妻子:你能说出一些吗?
丈夫:没问题。现在有许多设计原则,但是最基本的,就是SOLID(缩写),这五项原则。(感谢鲍勃叔叔,伟大OOD导师)。&
S& = 单一责任原则 O = 开闭原则 L& = Liscov替换原则 I& = 接口隔离原则 D = 依赖倒置原则
在下面的讨论中,我们将详细了解这些。
&翻译得不错哦!
话题:单一功能原则
作者:让我们先来看图,我们应该感谢制作这张图的人,因为它们真的太有趣了。
单一功能原则图
它的意思是:“如果你可以在一个设备中实现所有的功能,你却不能这样做”。为什么呢?因为从长远来看它增加了很多的可管理性问题。
&翻译得不错哦!
我们的翻译工作遵照 ,如果我们的工作有侵犯到您的权益,请及时联系我们
哈哈,是的,也有助有学习噢。。
要是不用学这些,就更不错啦,哈:)
要是不用学这些,就更不错啦,哈:)哈哈,我们去面向对象求个baoyang属性吧,或者找个父亲求继承吧
要是不用学这些,就更不错啦,哈:)哈哈,我们去面向对象求个baoyang属性吧,或者找个父亲求继承吧父类多半抽象,实现还靠自己啊浅谈面向对象编程 - 文章 - 伯乐在线
& 浅谈面向对象编程
1. OOP简介
面向对象编程(object-oriented programming)以下统一简称为OOP。世界上第一个OOP语言叫Simula,诞生于20世纪60年代,是它引入了对象、类、继承、虚过程等等这些概念。当时还没有“object-oriented”这个术语,这个术语是由第二个OOP语言Smalltalk的发明者Alan Kay提出来的,Smalltalk是“纯OO”的语言,在Smalltalk中一切皆对象:class、primitive type、code block(相当于匿名函数)等全是对象,对象行为的执行是通过向对象发送消息实现的,它没有命令式编程(imperative programming)中if、while这种语法结构,这些控制结构是通过向Boolean类型对象传递带有code block的消息实现的,Smalltalk是OOP语言中的代表,它影响了许多后来的OO语言,像Objective-C、Ruby、Java。 OOP作为一种思想,并不是由某个人发明出来的,各路OO大师都有自己的观点,所以对于到底什么是OOP,并没有一致的、权威的定义。本文所表达的OOP来自 Smalltalk + 自己肤浅的理解。
2. 对象的组成
2.1 协议 和 实现
对象(object) 表示一个由 状态(私有的) 和 操作(公开的)组成的单元
消息(message) 表示发送给一个对象让它执行某个操作的请求。一个对象能够响应的消息的集合叫做它的接口(interface)或协议(protocol),外界与对象进行交互应当只能通过这个对象的接口
消息代表一个对象能够响应什么操作,操作具体如何执行则是由方法(method)表示的。对象收到消息后决定调用哪个方法来进行处理,方法属于内部实现,也应是私有的。
Object i = 1 + 2;
// 向1这个对象发送“加”消息,消息参数是2
String str = i.toString();
// 向i这个对象发送toString消息,此时并不知道什么方法会被调用
Object i = 1 + 2;&&// 向1这个对象发送“加”消息,消息参数是2String str = i.toString();&&// 向i这个对象发送toString消息,此时并不知道什么方法会被调用
Smalltalk中,类通过定义protocol description来表示本类的实例可以响应哪些消息,方法则是单独定义,而在C++、Java这些语言中,没有这个区分,对于C++可以把protocol description理解成头文件里的函数声明,把方法理解成源文件中的函数定义。
对于C#/Java,可以把protocol description理解成接口中的方法列表,方法理解成实现类中的方法。
2.2 状态及处理过程的隐藏
对象的状态是私有的,只能由方法操作,方法是行为的具体实现,也是私有的,方法的调用是对象收到消息后由该对象自已进行的,这样对象的状态处理细节是完全隐藏的,这种特征就是“封装”。
汽车 与 封装
驾驶手动档汽车时不用直接去操作它引擎、变速齿轮,而是通过 变速杆、离合/制动/加速 踏板 这些接口,如果你不了解汽车的话,应该不知道变速杆和离合器是干什么用的,这其实是因为手动档汽车只是对引擎做了很浅的一层封装,某些接口其实暴露了其内部的实现 -& 汽油机,以至于在与汽车这个对象交互时需要注意一些规则比如松离合器要慢、换档前要踩离合器等等,以保证这个对象能正常工作,这就增加了使用者和这个对象间的耦合度,假设汽油机做了一些改进或者说引擎换成了电动机,那驾驶人的操作习惯就要作一些调整。
自动档汽车就封装得更好,只保留了 制动/加速 踏板,变速杆也被封装成了几个抽象档位,内部细节被隐藏了,对外耦合就小了。
2.2.1 隐藏的实现
JavaScript中可以通过闭包;Ruby中实例变量本身就是隐藏的,外部无法访问;C++/C#/Java可通过private关键字;C虽然语法上不支持,但程序员可以通过命名约定实现。
3. OOP的解耦利器 – 多态(subtype polymorphism)
多态从字面上讲是指“不同的对象以不同的方法响应相同的消息”,与过程式编程(procedural programming)不同,在OOP中对象是基本单元,函数存在于对象中,外部需要某个操作时向对象发送消息,对象来决定调用哪个函数,这样就将行为的实现者和行为的请求者解耦了。
举个例子,汽车、飞机、轮船这些交通工具,虽然它们的动力原理、操作方式都不一样,但它们都具有一些相同的接口:加速、获取速度,现要实现一个测速操作,可以测试任何交通工具。
Java示例:
// 交通工具
interface IVehicle{
public void speedUp();
// 获取当前速度
public int getCurrentSpeed();
class Automobile implements IVehicle{
private int currentSpeed = 0;
public void speedUp(){
System.out.println("汽车正在加速。。。");
++this.currentS
public int getCurrentSpeed(){
return this.currentS
class Aeroplane implements IVehicle{
private int currentSpeed = 0;
public void speedUp(){
System.out.println("飞机正在加速。。。");
this.currentSpeed += 3;
public int getCurrentSpeed(){
return this.currentS
public class Main{
public static void main(String[] args){
accelerationTest(new Automobile(), 5);
accelerationTest(new Aeroplane(), 5);
* 测试某个交通工具的加速度
* @param vehicle
* @param duration
加速多长时间
public static void accelerationTest(IVehicle vehicle, int duration){
for(int start = 0, end = start + start speedUp();
System.out.printf("%s在%d内将速度提升到%dn", vehicle.getClass().getName(), duration, vehicle.getCurrentSpeed());
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
// 交通工具interface IVehicle{&&// 加速&&public void speedUp();&&// 获取当前速度&&public int getCurrentSpeed();}&// 汽车class Automobile implements IVehicle{&&private int currentSpeed = 0;&&&public void speedUp(){&&&&System.out.println("汽车正在加速。。。");&&&&++this.currentSpeed;&&}&&public int getCurrentSpeed(){&&&&return this.currentSpeed;&&}}&// 飞机class Aeroplane implements IVehicle{&&private int currentSpeed = 0;&&&public void speedUp(){&&&&System.out.println("飞机正在加速。。。");&&&&this.currentSpeed += 3;&&}&&public int getCurrentSpeed(){&&&&return this.currentSpeed;&&}}&public class Main{&&public static void main(String[] args){&&&&accelerationTest(new Automobile(), 5);&&&&accelerationTest(new Aeroplane(), 5);&&}&&&/**&& * 测试某个交通工具的加速度&& *&& * @param vehicle&& 交通工具&& * @param duration&&加速多长时间&& */&&public static void accelerationTest(IVehicle vehicle, int duration){&&&&for(int start = 0, end = start + duration; start speedUp();&&&&}&&&&&System.out.printf("%s在%d内将速度提升到%dn", vehicle.getClass().getName(), duration, vehicle.getCurrentSpeed());&&}}
在上面代码中,accelerationTest虽然是交通工具的使用者,但却完全不受具体交通工具的影响,如果新添加一个Ship(船),accelerationTest一点都不用修改,因为accelerationTest和具体的交通工具都遵循了IVehicle这个协议,这样accelerationTest就知道:不管你具体是什么交通工具,反正都能够响应协议里的消息,到底调用什么方法来响应这些消息则交给了协议的实现者(即具体的交通工具)(这个从实现角度说的话应该是交给了编译器/解释器),而不是让accelerationTest根据具体的交通工具自己选择调用哪个函数(过程式的思维)。
3.1 多态的实现
duck-typing(鸭子类型)。因为动态语言中没有静态类型检查,所以能够做到“只要会呱呱叫的,就可以算是鸭子”,比如用JavaScript代码继续上面的示例:
var duck = new Duck();
// 创建一个鸭子对象
duck.speedUp = function(){ /*略*/ };
duck.getCurrentSpeed = function(){ /*略*/ };
// 这样就可以把一个鸭子对象当作“交通工具”测试其加速度
accelerationTest(duck, 5);
var duck = new Duck();&&// 创建一个鸭子对象duck.speedUp = function(){ /*略*/ };duck.getCurrentSpeed = function(){ /*略*/ };// 这样就可以把一个鸭子对象当作“交通工具”测试其加速度accelerationTest(duck, 5);
dynamic-dispatch(动态分派)
dynamic-dispatch是指在运行时去确定真正调用哪个函数,比如C++中的虚函数
即使是像C这种过程式的语言,也可利用函数指针实现多态:
* 交通工具虚函数表
struct vehicle_vtable{
void (*speed_up)(struct vehicle *self);
int (*get_current_speed)(struct vehicle *self);
* 交通工具
struct vehicle{
int current_speed_;
char name[100];
struct vehicle_
// 虚函数表
// 汽车加速方法
void automobile_speed_up(struct vehicle *self){
puts("汽车正在加速。。。");
++self-&current_speed_;
int automobile_get_current_speed(struct vehicle *self){
return self-&current_speed_;
// 汽车构造函数
struct vehicle *automobile_new(){
struct vehicle *self = (struct vehicle *)calloc(sizeof(struct vehicle));
self-&methods.speed_up = automobile_speed_
self-&methods.get_current_speed = automobile_get_current_
strcpy(self-&name, "汽车");
void automobile_destory(struct vehicle *self){
free(self);
// 飞机加速方法
void aeroplane_speed_up(struct vehicle *self){
puts("飞机正在加速。。。");
self-&current_speed_ += 3;
int aeroplane_get_current_speed(struct vehicle *self){
return self-&current_speed_;
// 飞机构造函数
struct vehicle *aeroplane_new(){
struct vehicle *self = (struct vehicle *)calloc(sizeof(struct vehicle));
self-&methods.speed_up = aeroplane_speed_
self-&methods.get_current_speed = aeroplane_get_current_
strcpy(self-&name, "飞机");
void aeroplane_destory(struct vehicle *self){
free(self);
void acceleration_test(struct vehicle *vehicle, int duration){
for(int i = 0; i methods.speed_up(vehicle);
printf("%s在%d内将速度提升到%dn", vehicle-&name, duration, vehicle-&methods.get_current_speed(vehicle));
int main(){
struct vehicle *automobile = automobile_new();
struct vehicle *aeroplane = aeroplane_new();
acceleration_test(automobile, 5);
acceleration_test(aeroplane, 5);
automobile_destory(automobile);
aeroplane_destory(aeroplane);
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
#include #include #include &struct vehicle;&/** * 交通工具虚函数表 */struct vehicle_vtable{&&void (*speed_up)(struct vehicle *self);&&int (*get_current_speed)(struct vehicle *self);};&/** * 交通工具 */struct vehicle{&&int current_speed_;&&char name[100];&&struct vehicle_vtable methods;&&// 虚函数表};&// 汽车加速方法void automobile_speed_up(struct vehicle *self){&&puts("汽车正在加速。。。");&&++self-&current_speed_;}&int automobile_get_current_speed(struct vehicle *self){&&return self-&current_speed_;}&// 汽车构造函数struct vehicle *automobile_new(){&&struct vehicle *self = (struct vehicle *)calloc(sizeof(struct vehicle));&&self-&methods.speed_up = automobile_speed_up;&&self-&methods.get_current_speed = automobile_get_current_speed;&&strcpy(self-&name, "汽车");&&return self;}&void automobile_destory(struct vehicle *self){&&free(self);}&// 飞机加速方法void aeroplane_speed_up(struct vehicle *self){&&puts("飞机正在加速。。。");&&self-&current_speed_ += 3;}&int aeroplane_get_current_speed(struct vehicle *self){&&return self-&current_speed_;}&// 飞机构造函数struct vehicle *aeroplane_new(){&&struct vehicle *self = (struct vehicle *)calloc(sizeof(struct vehicle));&&self-&methods.speed_up = aeroplane_speed_up;&&self-&methods.get_current_speed = aeroplane_get_current_speed;&&strcpy(self-&name, "飞机");&&return self;}&void aeroplane_destory(struct vehicle *self){&&free(self);}&void acceleration_test(struct vehicle *vehicle, int duration){&&for(int i = 0; i methods.speed_up(vehicle);&&printf("%s在%d内将速度提升到%dn", vehicle-&name, duration, vehicle-&methods.get_current_speed(vehicle));}&int main(){&&struct vehicle *automobile = automobile_new();&&struct vehicle *aeroplane = aeroplane_new();&&&acceleration_test(automobile, 5);&&acceleration_test(aeroplane, 5);&&&automobile_destory(automobile);&&aeroplane_destory(aeroplane);&&&return 0;}
4. 关于继承
个人认为OOP只有封装和多态,继承不属OOP的特性,它只是某些编程语言用来实现subtyping、多态和代码复用的一种手段。(subtyping和subclassing不是一回事,subtyping表达的是“可替换性”,subclassing就是指继承,某些语言只能用subclassing实现subtyping)
如果你看过一些OO的书,你会发现都会提到一个原则叫“组合优于继承”,组合表示的是一种包含关系,而继承是一种层级关系,为什么要用组合代替继承呢?
其实呢,继承也是包含关系,子类继承父类,也就包含了父类的状态,只不过这种包含关系是编译器帮你做了,还包含了方法的实现,所以能够响应父类能响应的消息,就实现了多态。那这一举两得,不是挺好吗?是挺好的,但不用继承照样能实现以上功能,而且继承有如下缺点:
大多数的语言都是单根继承,也就是只能继承一个父类,这样你就失去了一次使用继承的机会
继承的耦合度太高,子类和父类的关系在编译时被固定死了,不能动态切换,而组合关系可以在运行随意切换,一个例子就是装饰者模式 ,装饰者模式和继承类似实现的是一种“扩展”的目的,在装饰者模式中被扩展的对象是可选择的,而继承实现的这种扩展则是“死”的
什么时候用继承?
如果你想实现多态,正好又想复用实现,那么可以用继承。在使用继承前,建议想一下,使用它的目的是什么,如果仅仅为了实现多态就用接口,如果仅仅为了复用实现就用组合,继承虽然方便,但太重量级,又有限制,少用为妙。
4.1 为什么“正方形不是长方形”?
很多资料上都说继承表达的是一种“xx is a yy”的关系,我觉得这种说法不够准确,因为继承是用来实现多态的,是针对行为而言的,所以表达的是“xx 能够响应 yy 所能响应的消息”。
“正方形 继承 长方形”是一个经典的违背“里氏替换原则”的例子,常识上我们一般都认为“正方形是一种特殊的长方形”,貌似满足is-a的关系,可以用继承,但如果从接口考虑就不一样了:长方形能响应“操作长”、“操作宽”这两个消息,而正方形只能响应“操作边长”这一个消息,所以在OOP中我们要从接口上去考虑而不是简单的去判断是否具有“xx是一种特殊的yy”的关系。
OOP是用来在对象间统一协议,让对象间的交互只关心协议,而不关心实现,所以OOP只有封装和多态,至于其它的比如继承,只是语言层面提供的实用特性。
打赏支持我写出更多好文章,谢谢!
打赏支持我写出更多好文章,谢谢!
任选一种支付方式
关于作者:
可能感兴趣的话题
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线内容团队正试图以我们微薄的力量,把优秀的原创文章和译文分享给读者,为“快餐”添加一些“营养”元素。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2018 伯乐在线

我要回帖

更多关于 面向对象编程什么意思 的文章

 

随机推荐