对于Mixin(混合)、Trait(特性)这两个面向对象特性,总是让人觉得说不清道不明的感觉,其实众多设计语言里,这里面的一些概念也是相互参杂的,并不是又那么一个严格的定义或界限说哪种一定是Mixin,或者哪种一定是Trait。这两种语言设施的提出,它的本质实际上都是解决代码复用的问题。下面我们局一些例子来说明。介于本人的认识有限,在此也只是说说自己的看法。
本人认为这两个的涵义根据语言不同,而解释有所不同。但是它们的目的都是作为单继承不足的一种补充,或者是变相地实现多继承。实际上Java的接口也是变相的实现多继承,但是java的接口只是定义signature,没有实现体。在某种意义上Mixin和Trait这两者有点类似于抽象类,或者是有部分或全部实现体的Interface,但是在具体语言中,有表现出不一样的用法。总体上,笔者认为没有特别固定的或者是严格的区别。Mixin和Trait这两者都不能生成实例,否则就跟class没什么区别了。下面分别这两者的例子:
Scala trait
PHP traits
Ruby mixin
然后我们把这个模块混入到对象中去:
如上编码后,模块中的实例方法就会被混入到对象中:
勉强的区别
从上面看来,从使用上来说,可能看不出什么区别,但是如果说非要说区别的话,笔者通过搜索摘录和归纳了一些区别:
1)Mixin可能更多的是指动态语言,它是在执行到某个点的时候,将代码插入到其中来达到代码复用的效果。Trait更多的是编译过程中,通过一些静态手段赋值代码到类中使得其拥有Trait中的一些功能以达到代码复用的目的;
2)“Mixins may contain state, (traditional) traits don't.”这个区别比较弱,事实上Scala中Trait已经可以保存状态了(成员变量);
3)“Mixins use "implicit conflict resolution", traits use "explicit conflict resolution"”。这个区别可能是个明显的区别;但是如果某个语言它可以让Trait implicit resolve,那也没什么大不了。
4)“Mixins depends on linearization, traits are flattened.”这个区别可能有。至少Scala里面貌似Trait是Flattened处理的,跟Java嵌套类差不多。
下面是程序设计中,是该用类还是Mixin&Trait:
参考链接:
http://www.ibm.com/developerworks/java/library/j-jn8/index.html
http://stackoverflow.com/questions/925609/mixins-vs-traits
http://en.wikipedia.org/wiki/Trait_(computer_programming)
http://developer.51cto.com/art/200909/150722.htm
多继承 VS 单继承
引用
The developers of the Java language were well-versed in C++ and other languages that include multiple inheritance, whereby classes can inherit from an arbitrary number of parents. One of the problems with multiple inheritance is that it's impossible to determine which parent inherited functionality is derived from. This problem is called the diamond problem (see Resources). The diamond problem and other complexities that are inherent in multiple inheritance inspired the Java language designers to opt for single inheritance plus interfaces.
Interfaces define semantics but not behavior. They work well for defining method signatures and data abstractions, and all of the Java.next languages support Java interfaces with no essential changes. However, some cross-cutting concerns don't fit into a single-inheritance-plus-interfaces model.
在Java 中,一个类可以实现任意数量的接口。这个模型在声明一个类实现多个抽象的时候非常有用。不幸的是,它也有一个主要缺点。对于许多接口,大多数功能都可以用对于所有使用这个接口的类都有效的“样板”代码来实现。Java 没有提供一个内置机制来定义和使用这些可重用代码。相反的,Java 程序员必须使用一个特别的转换来重用一个已知接口的实现。在最坏的情况下,程序员必须复制粘贴同样的代码到不同的类中去。
Interfaces define semantics but not behavior. They work well for defining method signatures and data abstractions, and all of the Java.next languages support Java interfaces with no essential changes. However, some cross-cutting concerns don't fit into a single-inheritance-plus-interfaces model.
在Java 中,一个类可以实现任意数量的接口。这个模型在声明一个类实现多个抽象的时候非常有用。不幸的是,它也有一个主要缺点。对于许多接口,大多数功能都可以用对于所有使用这个接口的类都有效的“样板”代码来实现。Java 没有提供一个内置机制来定义和使用这些可重用代码。相反的,Java 程序员必须使用一个特别的转换来重用一个已知接口的实现。在最坏的情况下,程序员必须复制粘贴同样的代码到不同的类中去。
Mixin VS Trait
本人认为这两个的涵义根据语言不同,而解释有所不同。但是它们的目的都是作为单继承不足的一种补充,或者是变相地实现多继承。实际上Java的接口也是变相的实现多继承,但是java的接口只是定义signature,没有实现体。在某种意义上Mixin和Trait这两者有点类似于抽象类,或者是有部分或全部实现体的Interface,但是在具体语言中,有表现出不一样的用法。总体上,笔者认为没有特别固定的或者是严格的区别。Mixin和Trait这两者都不能生成实例,否则就跟class没什么区别了。下面分别这两者的例子:
Scala trait
class Person ; //实验用的空类 trait TTeacher extends Person { def teach //虚方法,没有实现 } trait TPianoPlayer extends Person { def playPiano = {println("I’m playing piano. ")} //实方法,已实现 } class PianoplayingTeacher extends Person with TTeacher with TPianoPlayer { def teach = {println("I’m teaching students. ")} //定义虚方法的实现 }
PHP traits
// the template trait TSingleton { private static $_instance = null; public static function getInstance() { if (null === self::$_instance) { self::$_instance = new self(); } return self::$_instance; } } class FrontController { use TSingleton; } // can also be used in already extended classes class WebSite extends SomeClass { use TSingleton; }
Ruby mixin
module Foo def bar puts "foo"; end end
然后我们把这个模块混入到对象中去:
class Demo include Foo end
如上编码后,模块中的实例方法就会被混入到对象中:
d=Demo.new d.bar
勉强的区别
从上面看来,从使用上来说,可能看不出什么区别,但是如果说非要说区别的话,笔者通过搜索摘录和归纳了一些区别:
1)Mixin可能更多的是指动态语言,它是在执行到某个点的时候,将代码插入到其中来达到代码复用的效果。Trait更多的是编译过程中,通过一些静态手段赋值代码到类中使得其拥有Trait中的一些功能以达到代码复用的目的;
2)“Mixins may contain state, (traditional) traits don't.”这个区别比较弱,事实上Scala中Trait已经可以保存状态了(成员变量);
3)“Mixins use "implicit conflict resolution", traits use "explicit conflict resolution"”。这个区别可能是个明显的区别;但是如果某个语言它可以让Trait implicit resolve,那也没什么大不了。
4)“Mixins depends on linearization, traits are flattened.”这个区别可能有。至少Scala里面貌似Trait是Flattened处理的,跟Java嵌套类差不多。
下面是程序设计中,是该用类还是Mixin&Trait:
引用
类还是Trait?
当我们考虑是否一个“概念”应该成为一个Trait 或者一个类的时候,记住作为混入的Trait 对于“附属”行为来说最有意义。如果你发现某一个Trait 经常作为其它类的父类来用,导致子类会有像父Trait 那样的行为,那么考虑把它定义为一个类吧,让这段逻辑关系更加清晰。(我们说像。。。的行为,而不是是。。。,因为前者是继承更精确的定义,基于Liskov Substitution Principle -- 例如参见 [Martin2003]。)
当我们考虑是否一个“概念”应该成为一个Trait 或者一个类的时候,记住作为混入的Trait 对于“附属”行为来说最有意义。如果你发现某一个Trait 经常作为其它类的父类来用,导致子类会有像父Trait 那样的行为,那么考虑把它定义为一个类吧,让这段逻辑关系更加清晰。(我们说像。。。的行为,而不是是。。。,因为前者是继承更精确的定义,基于Liskov Substitution Principle -- 例如参见 [Martin2003]。)
参考链接:
http://www.ibm.com/developerworks/java/library/j-jn8/index.html
http://stackoverflow.com/questions/925609/mixins-vs-traits
http://en.wikipedia.org/wiki/Trait_(computer_programming)
http://developer.51cto.com/art/200909/150722.htm
发表评论
-
pygraphviz 在windows 7/ python 2.7 下编译安装
2013-10-17 21:59 3340pygraphviz 在windows 7/ python 2 ... -
(转)Method Resolution Order (MRO) in new style Python classes
2013-09-20 22:08 980Stack Overflow link: http://st ... -
python实现的单子模式(附解释)
2013-07-13 21:06 2183一、通过metaclass来实现 class Sing ... -
SQL注入
2013-04-25 14:24 0http://www.ilovn.com/topic/wing ... -
Wing IDE 4.1 破解方法
2013-04-25 14:23 1840Wing IDE 4.1版本破解方法: 1、去官网下载最新版 ... -
【转】探索Python下的property, classmethod, staticmethod的实现
2013-04-08 21:22 1323转:http://marlonyao.iteye.com/bl ... -
python bytes and string 编码
2012-12-31 15:58 24354http://linchunai1212.blog.163.c ... -
Python subprocess
2012-12-31 15:07 3461Python标准库06 子进程 (subprocess包) 作 ... -
动态语言之三:语言的动态性
2012-10-24 21:53 2380转 http://blog.csdn.net/hongbo ... -
Python作用域和参数
2012-10-24 21:48 1100转(http://blog.lzp729.com/code-l ... -
Python作用域(转)
2012-10-24 21:45 1451python 变量作用域 分类: Python 2011-07 ... -
离线安装WindowBuilder
2011-10-30 16:04 10385贴的:http://justin-ray.iteye.com/ ... -
C里面的函数堆栈同C++的函数堆栈的区别
2010-10-14 19:45 2701五大内存分区 在C++中,内存分成5个区,他们分别是堆 ... -
全排列的新思路
2010-06-25 23:33 775以前 编过 一个 小程序 是 全排列的 递归算法; #incl ... -
让你的CPU利用率画正弦图
2010-06-24 23:05 1391#include "windows.h" ... -
动态规划 入门 二
2010-06-19 00:23 1227第二节 动态规划分类讨论 这里用状态维数对动态规划进行了分类 ... -
动态规划 入门一
2010-06-19 00:20 899对于动态规划,每个刚 ...
相关推荐
A Swift mixin for UITableViewCells and UICollectionViewCells.zip,A Swift mixin for reusing views easily and in a type-safe way (UITableViewCells, UICollectionViewCells, custom UIViews, ViewControllers...
MIXIN是使用ASM的Java的特性/混合框架
mixin是一个闪电交易快速的点点对的数字交道项目,它拥有非常好的技术栈。
modernizr-mixin, 在Sass中,针对测试的简单而全面的mixin hardwarebutton混合 一种简单的DRYier测试方法,在Sass中更快更。安装要求 ruby 3.4或者 LibSass 3.2Libsass警告:在 Libsass 3.2.3中有一个已知 Bug,它...
y-mixin 是来自阅文前端团队的 CSS 预处理器 mixin 库
小程序 mixin 混入, Page 选项合并
$ mixinNAME: mixin - A free and lightning fast peer-to-peer transactional network for digital assets.USAGE: mixin [global options] command [command options] [arguments...]VERSION: v0.7.0COMMANDS: ...
资源分类:Python库 所属语言:Python 资源全名:colcon_mixin-0.1.3-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
Mixin.js Mixin是将功能重复混合到原型JavaScript类中的简便方法。 它会自动处理覆盖的原型方法和调用构造函数的组合。 而且,它将通知已混合到另一个类中的混合构造函数。 这可用于构造依赖的混合层次结构。 安装 ...
#react-validate-mixin npm install react-validate-mixin或者 bower install react-validate-mixin##例子 var validate = require ( 'react-validate-mixin' ) ;var Compoent = React . createClass ( { mixins ...
面向Porter的Docker Compose Mixin 这是Porter的一个混合模块,提供了Docker Compose(docker-compose)CLI。混合声明要在捆绑包中使用此mixin,请这样声明: mixins :- docker-compose必需的扩展名要声明运行该包...
Mixin Client Java SDK这里是 Mixin Client Java SDK,其它语言的 Mixin SDK:NodeJS:Go:Python:更多 Mixin 开发资源:mixin_dev_resource:MiXin_Player:Java SDK v0.2当前版本 v0.2,主要功能是 Mixin 机器人:...
伪造混合素的例子 在Minecraft Forge中使用Mixin的示例
mixin混入来封装axios请求 我们通过mixin来封装axios请求这样每一个组件直接通过混入来进行axios请求。 不必每次需要时都要import引入一次 首先需要下载axios的包 //用npm、cnpm或者yarn都行 npm install axios ...
19-Mixin混入
19-Mixin混入
用于通知顶级组件的 mixin。 用法 首先,使用这个 mixin 创建一个组件: var NotifyMixin = require ( 'react-notify-mixin' ) ; var MyComp = React . createClass ( { mixins : [ NotifyMixin ] , handleClick...
按照mixin开发人员文档创建您的mixin应用。 单击按钮“单击以生成新的会话”。 现在,您将拥有机器人会话的秘密。 6位数字是您的资产PIN。UUID是新的会话ID。第三行是加密的PIN_TOKEN。RSA PRIVATE KEY是您的会话...
supergroup.mixin.one是“ Mixin中文群”的源代码,它是基于Mixin bot的无限成员组。 注意 !!! 在升级组之前,请先签出 。 准备 将./config/config.tpl.yaml复制到./config/config.yaml 替换config.yaml配置,...