写在前面的:
在Pony中,有两种方式扩展类、原类以及Actor: Trait(特性)和 Interface(接口)。编程语言中,扩展方式大体上就分为名义上(nominal)和结构上(structural)两种。看看官网是怎么从这方面介绍Pony的与众不同之处的:
Like other object-oriented languages, Pony has subtyping. That is, some types serve as categories that other types can be members of.
There are two kinds of subtyping in programming languages: nominal and structural. They’re subtly different, and most programming languages only have one or the other. Pony has both!
注意,不要把它理解成swift里的extension,更广的意义上,它是继承的替代品。更多详细资料请看知乎:subtyping和inheritance的区别是什么?
Trait(Nominal subtyping):
This kind of subtyping is called nominal because it is all about names.
用关键字trait去声明一个特性。一种特性里,只能有具体化的方法。另外,若欲对类去添加特性,要使用is关键字:
trait Named
fun name(): String => "Bob"
class Bob is Named
现在,如果调用Bob.name(),就会返回"Bob"。但是我们并未显式地向类中添加该方法,这便是特性的作用?!
那么怎样叠加特性呢?这很好办,不仅如此,还有多种方式去实现该需求?
①
trait Named
fun name(): String => "Bob"
trait Bald
fun hair(): Bool => false
class Bob is (Named & Bald)
②
trait Named
fun name(): String => "Bob"
trait Bald is Named
fun hair(): Bool => false
class Bob is Bald
在此处不多做解释,大家会意理解,择情使用即可。
Interface(Structural subtyping):
There’s another kind of subtyping, where the name doesn’t matter. It’s called structural subtyping, which means that it’s all about how a type is built, and nothing to do with names.
读了官文,感觉Pony对Interface的理解有点像duck-type (有一位博主写了关于所谓鸭子类型的一篇文章,可以参阅:https://www.cnblogs.com/youxin/p/3730215.html)
定义一个接口(interface):
interface HasName
fun name(): String
下面用一个例子来收束:
class Larry
fun name(): String => "Larry"
注意,Larry没有特性Named,尽管她拥有方法name()。但但但但是,Larry却不知不觉中实现了HasName接口!实际上,Bob和Larry都实现了这个接口。
我应该在我的代码中使用trait还是interface?(官方提问)
官方答案:
Should I use traits or interfaces in my own code? Both! Interfaces are more flexible, so if you’re not sure what you want, use an interface. But traits are a powerful tool as well: they stop accidental subtyping.
我的建议是:我们知道,interface会在不知不觉中匹配上,在某些地方它确实是缺点,但应该被理解为灵活性。在设计时,尽量使用trait使得你的代码可读性更强、安全性更强,在匹配时,尽量使用interface,因为它很灵活,也很狡猾。
下次再见咯!欢迎加入Pony语言QQ交流群:261824044!