基于对象和面向对象编程范式辨析和主流编程语言中的应用

基于对象和面向对象编程范式辨析和主流编程语言中的应用 copyright dedecms

前言

织梦好,好织梦

         本文的目的是想告诉大家,为什么C++的模板这么强大。为什么Ruby的Duck Typing(像鸭子那样编程)这么强大! 织梦内容管理系统

基于对象和面向对象编程范式 本文来自织梦

关于基于对象和面向对象编程范式,我有着不同于传统的理解。我认为我的理解更能体现出这2个范式的本意。 织梦好,好织梦

基于对象,就是使用类封装操作和操作依赖的数据。用类来表示一个概念。类的公共成员,包括函数和数据,就是类的接口,也叫作抽象数据类型(ADT)。

本文来自织梦

面向对象,就是使用类的接口实现机制来表示操作。一个接口使用一组相关的公共函数代表一个概念的操作。一些类实现这个接口。这个实现类可以互换。 织梦好,好织梦

在使用中,使用接口的指针或者引用来调用对象。具体的对象是接口的某个实现类。可以不改变代码,仅仅改变实际的对象来实现动态修改系统的行为。 dedecms.com

这就是“动态多态”的能力。

本文来自织梦

面向对象的动态多态能力,使抽象能力比函数更进一步。

本文来自织梦

动态多态,在实现中是使用了“虚函数”机制来实现的。 copyright dedecms

        对象指向的本类的虚函数表来查得真正需要调用的方法。 织梦好,好织梦

语言特性对比表 copyright dedecms

                      C++       Java       .NET     Ruby           

本文来自织梦

类型           强类型     强类型   强类型    强类型 内容来自dedecms

静态/动态       静态   静态检验类型动态解释执行   动态 织梦好,好织梦

支持面向过程   是         否         否        否

内容来自dedecms

支持基于对象   是         否         是        是

本文来自织梦

支持范型       否         是          是       否

织梦内容管理系统

支持模板       是         否         否         否 本文来自织梦

C++通过抽象基类来作为接口,通过对抽象基类的继承来实现这个接口。 织梦好,好织梦

Java和.NET都提供了Interface接口类型。实现接口的类实现了这个机制。 织梦内容管理系统

所以说,C++,Java,.NET都支持面向对象的编程范式。特别是java,它只支持面向对象(也就是动态多态)这一种编程范式。其他一概不支持! 内容来自dedecms

动态类型语言,如Ruby,JavaScript都没有接口。为什么呢? 织梦内容管理系统

考虑一下,动态类型语言尽管有类型。但是变量都是没有类型的。如 织梦内容管理系统

//伪代码

织梦好,好织梦

Class Dao1{ 织梦好,好织梦

   Public void save(model){ 内容来自dedecms

     //保存数据

本文来自织梦

} copyright dedecms

}

织梦内容管理系统

Class Dao2{

内容来自dedecms

   Public void save(model){

dedecms.com

     //保存数据 织梦内容管理系统

}

织梦好,好织梦

} 内容来自dedecms

Class Service{

织梦内容管理系统

   @dao; 织梦好,好织梦

    Public void save(model){ 内容来自dedecms

       this.dao.save();

织梦内容管理系统

}

织梦好,好织梦

} dedecms.com

//调用代码: 织梦好,好织梦

New Service(new Dao1).save(model); dedecms.com

New Service(new Dao2).save(model);

dedecms.com

这里,Dao1,Dao2这2个类需要实现一个共同的接口吗? dedecms.com

动态类型语言中,尽管对象是有类型的,但是变量(实际是指向对象的指针)是没有类型的。Service类的变量dao可以是任何类型!只要那个对象所属的类型有Public void save(model);这样签名的函数即可!

织梦内容管理系统

动态类型语言中,根本不需要Java等静态语言中的接口的概念。这就是动态类型语言著名的Duck Typing“像鸭子一样编程”的理念。 本文来自织梦

         Java这样的静态类型语言当然也有自己的优点。那就是通过强制实现接口。可以保证程序员不会因为笔误而调用错误的类型。

织梦好,好织梦

         但是,在实践中,动态类型语言的Duck Typing却是更加灵活,更胜一筹!

织梦内容管理系统

动态语言既然没有接口,那么它们调用的方法,也就是该类的方法或者继承的方法,就不需要虚函数表,也就不是面向对象的“动态多态”机制了。

copyright dedecms

Ruby,JavaScript的“多态”机制,是“动态基于对象”的机制。 内容来自dedecms

根据我的定义标准,Ruby,JavaScript等动态类型语言是“基于对象”编程范式的语言。是“动态基于对象”的编程语言。而非面向对象编程语言。 织梦内容管理系统

可能你会说,Ruby,JavaScript 都有“继承”的能力,怎么能说它们不是面向对象编程语言呢? 本文来自织梦

“继承”,只是一种代码重用机制。和编程范式这样的设计问题根本答不上边。甚至,我反对大量使用继承来重用代码(少数特殊情况除外)。我们应该使用“组合”来重用代码。

织梦好,好织梦

因为继承会造成类和类之间的实现依赖。而组合就不会有这种依赖关系。我们只要写上一些通道代码就可换取类和类之间的解耦。 copyright dedecms

好了,现在再让我们看看C++的基于对象的编程范式。

织梦好,好织梦

C++的基于对象,就是设计一些类,把函数和函数需要的数据封装在一个类中。但是,如何实现真正的ADT(抽象数据类型)呢?

织梦内容管理系统

这样:头文件代表抽象数据类型。实现文件中提供定义。如果一个抽象数据类型需要多个实现呢?

dedecms.com

我们为一个类提供几个实现文件。用哪一个就提供哪一个版本。这样显然非常繁琐。事实上也没有人会这样编程!

织梦内容管理系统

那怎么办呢?难道C++这样的静态类型语言的“基于对象”编程范式,注定就不能实现多态吗?C++的模板机制解决了这个问题!(在没有彻底搞懂模板之前,我一直用面向对象编程范式使用C++,因此对C++是怨声载道!) 内容来自dedecms

如:

内容来自dedecms

//伪码 dedecms.com

Template<tyepe TDao >Class Service{

dedecms.com

 Private:

dedecms.com

   TDao* dao=new TDao();

本文来自织梦

 Public: dedecms.com

    Void save(Model model){ 本文来自织梦

     This->dao->save(model); 本文来自织梦

} 本文来自织梦

}

内容来自dedecms

//使用

织梦好,好织梦

   Model* model=new Model();

dedecms.com

   Service<Dao>* service=new Service<Dao>();

dedecms.com

   Service->save(model); dedecms.com

    假设Dao这个类有Public: 织梦好,好织梦

    Void save(Model model);这样签名的方法。 dedecms.com

    Void save(Model model)这个函数就是TDao这个抽象数据类型(ADT)公布的方法。

dedecms.com

任何类只要有这样的方法,就满足TDao这个ADT,就可以在Service模板类中使用! 内容来自dedecms

     对照上面Ruby的伪码,我们可以发现: 织梦内容管理系统

1,C++的“模板支持的基于对象”的编程范式,仅仅比动态基于对象语言多了模板参数类型的声明。

copyright dedecms

而且,C++可以直接在模板类内部实例化类型。真正的类型只有在编译时才指定。而动态基于对象的语言因为没有代表类型的符号,不能实例化未知的类型。 copyright dedecms

2,C++的“模板支持的基于对象”的编程范式,指定了模板参数类型,也就是在编译时需要验证类型。这就比动态基于对象的语言多了编译时静态验证类型这一道关卡,更加安全可靠。 copyright dedecms

   

内容来自dedecms

C++中模板之所以伟大,正是因为它是静态语言中支持基于对象编程范式的银弹!

织梦内容管理系统

C++的“模板支持的基于对象”的编程范式,令C++拥有了与Ruby等动态基于对象编程语言的多态能力相比肩的顶级语言!

本文来自织梦

总结

dedecms.com

基于对象和面向对象编程共有三种范式。它们提供了强大的动态或者静态多态能力,使用它们编程,将令你的程序面向抽象,易于更换。 dedecms.com

1,“模板支持的基于对象”的编程范式。这种编程范式适用于静态类型的语言。提供了静态多态的能力。典型的如C++。 本文来自织梦

模板不同于范型。模板是一种编译时的代码生成机制。而泛型是对模板的模拟。在java和.net中都使用类型转换机制而不是源代码生成机制来实现。

dedecms.com

我认为模板优于范型。.NET的范型实现的要比Java好。.NET中可以使用new()关键字实现在范型类中创建未知类型的对象,而java中不可以。 内容来自dedecms

“模板支持的基于对象”的编程范式实现了编译时静态的多态。具备了强大的静态多态能力。而且生成的代码运行速度快。 内容来自dedecms

缺点是,如果写得不好,容易发生源代码扩张的问题。

dedecms.com

2,“静态类型语言”的面向对象的编程范式。这种编程范式适用于静态类型的语言。提供了动态多态的能力。典型的如Java,NET。 dedecms.com

使用接口和实现接口的技术,实现了动态多态。并且可以利用静态类型检验的优势,进行更加完善的类型安全检查。 织梦好,好织梦

    C++也具有进行这一编程范式的能力。但是,C++对于这一编程范式的支持并不是很好。因此,C++编程中,应该优先使用“模板支持的基于对象”的编程范式。然后再考虑使用“静态类型语言”的面向对象的编程范式实现多态。

dedecms.com

3,“动态类型语言”的基于对象的编程范式。使用Duck Typing“像鸭子一样编程”的编程理念。这种编程范式适用于动态类型的语言。它们有类型,但是变量不确定类型。典型的如Ruby。这也实现了动态的多态能力。 copyright dedecms

来自:基于对象和面向对象编程范式辨析和主流编程语言中的应用

织梦内容管理系统

相关文章