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

 

基于对象和面向对象编程范式辨析和主流编程语言中的应用
 
前言
         本文的目的是想告诉大家,为什么C++的模板这么强大。为什么Ruby的Duck Typing(像鸭子那样编程)这么强大!
 
 
 
 
 
 
基于对象和面向对象编程范式
关于基于对象和面向对象编程范式,我有着不同于传统的理解。我认为我的理解更能体现出这2个范式的本意。
 
基于对象,就是使用类封装操作和操作依赖的数据。用类来表示一个概念。类的公共成员,包括函数和数据,就是类的接口,也叫作抽象数据类型(ADT)。
 
面向对象,就是使用类的接口实现机制来表示操作。一个接口使用一组相关的公共函数代表一个概念的操作。一些类实现这个接口。这个实现类可以互换。
在使用中,使用接口的指针或者引用来调用对象。具体的对象是接口的某个实现类。可以不改变代码,仅仅改变实际的对象来实现动态修改系统的行为。
这就是“动态多态”的能力。
面向对象的动态多态能力,使抽象能力比函数更进一步。
动态多态,在实现中是使用了“虚函数”机制来实现的。
        对象指向的本类的虚函数表来查得真正需要调用的方法。
 
语言特性对比表
                      C++        Java       .NET     Ruby           
类型            强类型      强类型    强类型     强类型
静态/动态        静态    静态检验类型动态解释执行    动态
支持面向过程    是          否          否         否
支持基于对象    是          否          是         是
支持范型        否          是           是        否
支持模板        是          否          否          否
 
 
 
 
C++通过抽象基类来作为接口,通过对抽象基类的继承来实现这个接口。
Java和.NET都提供了Interface接口类型。实现接口的类实现了这个机制。
所以说,C++,Java,.NET都支持面向对象的编程范式。特别是java,它只支持面向对象(也就是动态多态)这一种编程范式。其他一概不支持!
 
动态类型语言,如Ruby,JavaScript都没有接口。为什么呢?
考虑一下,动态类型语言尽管有类型。但是变量都是没有类型的。如
//伪代码
Class Dao1{
   Public void save(model){
     //保存数据
}
}
Class Dao2{
   Public void save(model){
     //保存数据
}
}
 
Class Service{
   @dao;
    Public void save(model){
       this.dao.save();
}
 
}
//调用代码:
New Service(new Dao1).save(model);
New Service(new Dao2).save(model);
 
 
这里,Dao1,Dao2这2个类需要实现一个共同的接口吗?
动态类型语言中,尽管对象是有类型的,但是变量(实际是指向对象的指针)是没有类型的。Service类的变量dao可以是任何类型!只要那个对象所属的类型有Public void save(model);这样签名的函数即可!
动态类型语言中,根本不需要Java等静态语言中的接口的概念。这就是动态类型语言著名的Duck Typing“像鸭子一样编程”的理念。
         Java这样的静态类型语言当然也有自己的优点。那就是通过强制实现接口。可以保证程序员不会因为笔误而调用错误的类型。
          但是,在实践中,动态类型语言的Duck Typing却是更加灵活,更胜一筹!
 
动态语言既然没有接口,那么它们调用的方法,也就是该类的方法或者继承的方法,就不需要虚函数表,也就不是面向对象的“动态多态”机制了。
Ruby,JavaScript的“多态”机制,是“动态基于对象”的机制。
根据我的定义标准,Ruby,JavaScript等动态类型语言是“基于对象”编程范式的语言。是“动态基于对象”的编程语言。而非面向对象编程语言。
 
可能你会说,Ruby,JavaScript 都有“继承”的能力,怎么能说它们不是面向对象编程语言呢?
“继承”,只是一种代码重用机制。和编程范式这样的设计问题根本答不上边。甚至,我反对大量使用继承来重用代码(少数特殊情况除外)。我们应该使用“组合”来重用代码。
因为继承会造成类和类之间的实现依赖。而组合就不会有这种依赖关系。我们只要写上一些通道代码就可换取类和类之间的解耦。
 
好了,现在再让我们看看C++的基于对象的编程范式。
C++的基于对象,就是设计一些类,把函数和函数需要的数据封装在一个类中。但是,如何实现真正的ADT(抽象数据类型)呢?
这样:头文件代表抽象数据类型。实现文件中提供定义。如果一个抽象数据类型需要多个实现呢?
我们为一个类提供几个实现文件。用哪一个就提供哪一个版本。这样显然非常繁琐。事实上也没有人会这样编程!
 
那怎么办呢?难道C++这样的静态类型语言的“基于对象”编程范式,注定就不能实现多态吗?C++的模板机制解决了这个问题!(在没有彻底搞懂模板之前,我一直用面向对象编程范式使用C++,因此对C++是怨声载道!)
如:
//伪码
Template<tyepe TDao >Class Service{
 Private:
   TDao* dao=new TDao();
 Public:
    Void save(Model model){
     This->dao->save(model);
 
}
}
 
//使用
   Model* model=new Model();
   Service<Dao>* service=new Service<Dao>();
   Service->save(model);
 
    假设Dao这个类有Public:
    Void save(Model model);这样签名的方法。
 
    Void save(Model model)这个函数就是TDao这个抽象数据类型(ADT)公布的方法。
任何类只要有这样的方法,就满足TDao这个ADT,就可以在Service模板类中使用!
 
     对照上面Ruby的伪码,我们可以发现:
1,C++的“模板支持的基于对象”的编程范式,仅仅比动态基于对象语言多了模板参数类型的声明。
而且,C++可以直接在模板类内部实例化类型。真正的类型只有在编译时才指定。而动态基于对象的语言因为没有代表类型的符号,不能实例化未知的类型。
2,C++的“模板支持的基于对象”的编程范式,指定了模板参数类型,也就是在编译时需要验证类型。这就比动态基于对象的语言多了编译时静态验证类型这一道关卡,更加安全可靠。
   
 
C++中模板之所以伟大,正是因为它是静态语言中支持基于对象编程范式的银弹!
C++的“模板支持的基于对象”的编程范式,令C++拥有了与Ruby等动态基于对象编程语言的多态能力相比肩的顶级语言!
 
 
总结
基于对象和面向对象编程共有三种范式。它们提供了强大的动态或者静态多态能力,使用它们编程,将令你的程序面向抽象,易于更换。
1,“模板支持的基于对象”的编程范式。这种编程范式适用于静态类型的语言。提供了静态多态的能力。典型的如C++。
模板不同于范型。模板是一种编译时的代码生成机制。而泛型是对模板的模拟。在java和.net中都使用类型转换机制而不是源代码生成机制来实现。
我认为模板优于范型。.NET的范型实现的要比Java好。.NET中可以使用new()关键字实现在范型类中创建未知类型的对象,而java中不可以。
“模板支持的基于对象”的编程范式实现了编译时静态的多态。具备了强大的静态多态能力。而且生成的代码运行速度快。
缺点是,如果写得不好,容易发生源代码扩张的问题。
 
2,“静态类型语言”的面向对象的编程范式。这种编程范式适用于静态类型的语言。提供了动态多态的能力。典型的如Java,NET。
使用接口和实现接口的技术,实现了动态多态。并且可以利用静态类型检验的优势,进行更加完善的类型安全检查。
    C++也具有进行这一编程范式的能力。但是,C++对于这一编程范式的支持并不是很好。因此,C++编程中,应该优先使用“模板支持的基于对象”的编程范式。然后再考虑使用“静态类型语言”的面向对象的编程范式实现多态。
 
3,“动态类型语言”的基于对象的编程范式。使用Duck Typing“像鸭子一样编程”的编程理念。这种编程范式适用于动态类型的语言。它们有类型,但是变量不确定类型。典型的如Ruby。这也实现了动态的多态能力。
 
 
 
 
 
 
 
 
良少 CSDN认证博客专家 数据分析 PyTorch 神经网络
资深挨踢人士,精通Python,C,Java,JavaScript,Linux内核,网络协议,虚拟化,云计算,分布式存储,kubernetes,数据仓库等技术。擅长微服务架构设计,DevOps。目前致力于以Fintech助力普惠金融。
已标记关键词 清除标记
相关推荐
<p> <strong><span style="font-size:16px;color:#003399;">会用Python分析金融数据 or 金融行业会用Python</span></strong> </p> <p> <strong><span style="font-size:16px;color:#003399;">职场竞争力更高</span></strong> </p> <p> <br /> </p> <p> <img src="https://img-bss.csdnimg.cn/202012231042221925.png" alt="" /> </p> <p> <br /> </p> <p> <br /> </p> <p> <strong><span style="font-size:16px;color:#003399;">Python金融数据分析入门到实战</span></strong> </p> <p> <strong><span style="font-size:16px;color:#003399;">Get√金融行业数据分析必备技能</span></strong> </p> <p> <img src="https://img-bss.csdnimg.cn/202012231042438069.png" alt="" /> </p> <p> <br /> </p> <p> <br /> </p> <p> <strong><span style="font-size:16px;color:#003399;">以股票量化交易为应用场景</span></strong> </p> <p> <strong><span style="font-size:16px;color:#003399;">完成技术指标实现的全过程</span></strong> </p> <p> <br /> </p> <p> <span style="font-size:14px;">课程选取股票量化交易为应用场景,由股票数据的获取、技术指标的实现,逐步进阶到策略的设计</span><span style="font-size:14px;">和回测,由浅入深、由技术到思维地为同学们讲解Python金融数据分析在股票量化交易中的应用</span><span style="font-size:14px;">。</span> </p> <p> <br /> </p> <p> <span style="font-size:14px;"><br /> </span> </p> <p> <img src="https://img-bss.csdnimg.cn/202012231043183686.png" alt="" /> </p> <p> <br /> </p> <p> <br /> </p> <p> <strong><span style="font-size:16px;color:#003399;">以Python为编程语言</span></strong> </p> <p> <strong><span style="font-size:16px;color:#003399;">解锁3大主流数据分析工具</span></strong> </p> <p> <br /> </p> <p> <span style="font-size:14px;">Python做金融具有先天优势,课程提取了Python数据分析工具NumPy、Pandas及可视化工具</span><span style="font-size:14px;">Matplotlib的关键点详细讲解,帮助同学掌握数据分析的关键技能。</span> </p> <p> <img src="https://img-bss.csdnimg.cn/202012231043472858.png" alt="" /> </p> <p> <strong><span style="font-size:16px;color:#003399;"><br /> </span></strong> </p> <p> <strong><span style="font-size:16px;color:#003399;">2大购课福利</span></strong> </p> <p> <strong><span style="font-size:16px;color:#003399;"><br /> </span></strong> </p> <p> <img src="https://img-bss.csdnimg.cn/202012300628195864.png" alt="" /> </p>
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:白松林 返回首页