.NET有Extension Methods。当你:
using System.Linq;
然后,你的所有数组对象神奇般地“拥有”了Contains, Count, GroupBy, OrderBy等一系列“前所未有”的方法。你感觉你的“Array”类被人注入了额外的东西。
C#的Extension Method定义为静态方法。如果第一个参数加上了this修饰符,那么这个方法就被认为是Extension Method。该方法被加在this修饰的参数的类型上。
注意ShyBoyKissSupport.Kiss方法
using System;
namespace BoyKiss
{
abstract class Child
{
public string name { get; set; }
protected Child(string name)
{
this.name = name;
}
}
class Boy : Child
{
public Boy(string name) : base(name) {}
public void Kiss(Girl girl)
{
System.Console.WriteLine("{0} kisses {1}", name, girl.name);
girl.OnKissed(this);
}
}
class Girl : Child
{
public Girl(string name) : base(name) {}
public void OnKissed(Child child)
{
System.Console.WriteLine("{0} is kissed by {1}", name, child.name);
}
}
class ShyBoy : Child
{
public ShyBoy(string name) : base(name) {}
// Kiss method is missing
}
static class ShyBoyKissSupport {
public static void kiss(this ShyBoy me, Girl girl)
{
System.Console.WriteLine("{0} bravely kisses {1}", me.name, girl.name);
girl.OnKissed(me);
}
}
class MainClass
{
public static void Main(string[] args)
{
var b = new Boy("Bob");
var g = new Girl("Alice");
b.Kiss(g);
var b2 = new ShyBoy("Peter");
var g2 = new Girl("Wendy");
b2.Kiss(g2);
}
}
}
/* 输出:
Bob kisses Alice
Alice is kissed by Bob
Peter bravely kisses Wendy
Wendy is kissed by Peter
*/
然后ShyBoy类就拥有了Kiss方法。
-----------------
下面讨论Scala语言。所涉及的问题域如下:
package boykiss
class Child(val name:String) {
}
class Boy(name:String) extends Child(name) {
def kiss(girl: Girl) {
println(name+" kisses "+girl.name);
girl.onKissed(this);
}
}
class Girl(name:String) extends Child(name) {
def onKissed(child : Child) {
println(name +" is kissed by " + child.name);
}
}
class ShyBoy(name:String) extends Child(name) {
// kiss method is missing.
}
注意到,这个ShyBoy类仍然没有kiss方法。我们需要一定的代码给他加上。
Scala没有Extension Method,但是有隐式类型转换。如果一个方法加上了implicit修饰符,那么它就认为是一个隐式转换方法。如下:
object ShyBoyKissSupport {
implicit def fromShyBoy(b : ShyBoy) = new ShyBoyWrapper(b);
}
class ShyBoyWrapper(me: ShyBoy) {
def kiss(girl: Girl) {
println(me.name+" bravely kisses "+girl.name);
girl.onKissed(me);
}
}
object定义了单例对象ShyBoyKissSupport。它的fromShyBoy方法有implicit修饰,因此会自动把ShyBoy对象用该方法转换成ShyBoyWrapper类的对象。
ShyBoyWrapper类只不过是一个封装器,封装了一个ShyBoy。它具有kiss方法。
主程序这样写:
import ShyBoyKissSupport.fromShyBoy
object Main {
def main(args : Array[String]) {
val b = new Boy("Bob");
val g = new Girl("Alice");
b.kiss(g);
val b2 = new ShyBoy("Peter");
val g2 = new Girl("Wendy");
b2.kiss(g2);
}
}
/* 输出:
Bob kisses Alice
Alice is kissed by Bob
Peter bravely kisses Wendy
Wendy is kissed by Peter
*/
这个import ShyBoyKissSupport.fromShyBoy在这里是必要的,否则在下面的代码中,这个隐式转换方法不可见,也就不能自动隐式转换。实际中还可以用package object完成这个工作。
当调用b2.kiss(g2)的时候,因为b2没有kiss方法,但有隐式转换函数fromShyBoy,而且ShyBoyWrapper有kiss方法。所以,b2会先被隐式转换成ShyBoyWrapper,然后调用ShyBoyWrapper.kiss方法。
总结:Scala的隐式转换可以完成类似Extension Method的功能。
分享到:
相关推荐
赠送jar包:scala-parser-combinators_2.12-1.1.0.jar; 赠送原API文档:scala-parser-combinators_2.12-1.1.0-javadoc.jar; 赠送源代码:scala-parser-combinators_2.12-1.1.0-sources.jar; 赠送Maven依赖信息...
赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...
赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...
赠送jar包:scala-xml_2.11-1.0.4.jar; 赠送原API文档:scala-xml_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.4-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.4.pom; 包含翻译后的API...
赠送jar包:scala-xml_2.12-1.0.6.jar; 赠送原API文档:scala-xml_2.12-1.0.6-javadoc.jar; 赠送源代码:scala-xml_2.12-1.0.6-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.12-1.0.6.pom; 包含翻译后的API...
赠送jar包:scala-xml_2.11-1.0.1.jar; 赠送原API文档:scala-xml_2.11-1.0.1-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.1-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.1.pom; 包含翻译后的API...
赠送jar包:scala-parser-combinators_2.11-1.0.4.jar; 赠送原API文档:scala-parser-combinators_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-parser-combinators_2.11-1.0.4-sources.jar; 赠送Maven依赖信息...
赠送jar包:scala-xml_2.11-1.0.5.jar; 赠送原API文档:scala-xml_2.11-1.0.5-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.5-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.5.pom; 包含翻译后的API...
赠送jar包:scala-parser-combinators_2.11-1.0.4.jar; 赠送原API文档:scala-parser-combinators_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-parser-combinators_2.11-1.0.4-sources.jar; 包含翻译后的API...
赠送jar包:scala-reflect-2.12.10.jar; 赠送原API文档:scala-reflect-2.12.10-javadoc.jar; 赠送源代码:scala-reflect-2.12.10-sources.jar; 赠送Maven依赖信息文件:scala-reflect-2.12.10.pom; 包含翻译后...
赠送jar包:scala-compiler-2.11.12.jar; 赠送原API文档:scala-compiler-2.11.12-javadoc.jar; 赠送源代码:scala-compiler-2.11.12-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.11.12.pom; 包含...
读书笔记:scala0522是Scala编程内容
- 隐式转换:Scala允许隐式参数和隐式转换,有助于代码简洁性,但需谨慎使用以避免混淆。 - 类型推断:Scala具有强大的类型推断能力,允许编写更少的类型声明,提高代码可读性。 - 泛型:泛型提供了一种方式来...
读书笔记:scala编程
3. 隐式转换:Scala支持隐式转换,允许在特定上下文中将一个类型转换为另一个类型,提高代码的简洁性。 三、函数式编程概念 1. 高阶函数:如前所述,函数可以作为一等公民,可以赋值给变量、作为参数或返回结果。 ...
赠送jar包:scala-compiler-2.11.8.jar; 赠送原API文档:scala-compiler-2.11.8-javadoc.jar; 赠送源代码:scala-compiler-2.11.8-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.11.8.pom; 包含翻译后...
赠送jar包:scala-compiler-2.12.7.jar; 赠送原API文档:scala-compiler-2.12.7-javadoc.jar; 赠送源代码:scala-compiler-2.12.7-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.12.7.pom; 包含翻译后...
赠送jar包:scala-compiler-2.11.0.jar; 赠送原API文档:scala-compiler-2.11.0-javadoc.jar; 赠送源代码:scala-compiler-2.11.0-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.11.0.pom; 包含翻译后...
读书笔记:scala函数编程
读书笔记:scala编程指导