`
edge
  • 浏览: 69634 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Scala概述(五)抽象(2.3)

阅读更多

族多态和self类型(Family polymorphism and self types.Scala的抽象类型概念非常适合于描述相互之间协变的一族(families)类型,这种概念称作族多态。例如:考虑发布/订阅模式,它有两个主要类型:subjectsobserversSubjects定义了subscribe方法,用于给observers进行注册,同时还有一个publish方法,用于通知所有的注册者;通知是通过调用所有注册者的notify方法实现的。一般来说,当subject的状态发生改变时,会调用publish方法。一个subject可以有多个observers,一个observer也可以观察多个subjectSubscribe方法一般用observer的标识为参数,而notify方法则以发出通知的subject对象为参数。因此,这两个类型在方法签名中都引用到了对方。

这个模式的所有要素都在如下系统中:

abstract class SubjectObserver {

type S <: Subject

type O <: Observer

abstract class Subject requires S {

private var observers: List[O] = List()

def subscribe(obs: O) =

observers = obs :: observers

def publish =

for (val obs <- observers) obs.notify(this)

}

 

trait Observer {

def notify(sub: S): unit

}

}

顶层的SubjectObserver类包含两个类成员:一个用于subject,一个用于observerSubject类定义了subscribe方法和publish方法,并且维护一个所有注册的observer的列表。Observer这个trait只定义了一个抽象方法notify

需要注意的是,SubjectObserver并没有直接引用对方,因为这种“硬”引用将会影响客户代码对这些类进行协变的扩展。相反,SubjectOberver定义了两个抽象类型SO,分别以SubjectObserver作为上界。Subjectobserver的类型分别通过这两个抽象类型引用对方。

另外还要注意,Subject类使用了一个特殊的标注requires

abstract class Subject requires S { ...

这个标注表示Subject类只能作为S的某个子类被实例化,这里S被称作Subjectself-type。在定义一个类的时候,如果指定了self-type,则这个类定义中出现的所有this都被认为属于这个self-type类型,否则被认为是这个类本身。在Subject类中,必须将self-type指定为S,才能保证obs.notify(this)调用类型正确

Self-type可以是任意类型,并不一定与当前正在定义的类型相关。依靠如下两个约束,类型正确性仍然可以得到保证:(1)一个类型的self-type必须是其所有父类型的子类,(2)当使用new 对一个类进行实例化时,编译器将检查其self-type必须是这个类的父类。

这个publish/subscribe模式中所定义的机制可以通过继承SubjectObserver,并定义应用相关的SubjectObserver类来使用。例如下面的SensorReader对象,将传感器(sensors)作为subjects,而将显示器(displays)作为observers

object SensorReader extends SubjectObserver {

type S = Sensor

type O = Display

abstract class Sensor extends Subject {

val label: String

var value: double = 0.0

def changeValue(v: double) = {

value = v

publish

}

}

 

class Display extends Observer {

def println(s: String) = ...

def notify(sub: Sensor) =

println(sub.label + " has value " + sub.value)

}

}

在这个对象中,SSensor限定,而ODisplay限定,从而原先的两个抽象类型现在分别通过覆盖而获得定义,这种“系绳节”(“tying the knot”)在创建对象实例的时候是必须的。当然,用户也可以再定义一个抽象的SensorReader类型,未来再通过继承进行实例化。此时,这两个抽象类型也可以通过抽象类型来覆盖,如:

class AbsSensorReader extends SubjectObserver {

type S <: Sensor

type O <: Display

...

}

下面的代码演示了SensorReader如何使用:

object Test {

import SensorReader._

val s1 = new Sensor { val label = "sensor1" }

val s2 = new Sensor { val label = "sensor2" }

def main(args: Array[String]) = {

val d1 = new Display; val d2 = new Display

s1.subscribe(d1); s1.subscribe(d2)

s2.subscribe(d1)

s1.changeValue(2); s2.changeValue(3)

}

}

另外值得注意的是其中的import语句,它使Test可以直接访问SensorReader的成员,而无需前缀。ScalaImportJava中用法更广泛,可以在任何地方使用,可以从任何对象中导入成员,而不仅仅从一个package中。

分享到:
评论
1 楼 edge 2008-12-31  
这个部分比较体现Scala在抽象类型方面的特点,可惜为此语法的复杂性又上升到了新的高度

相关推荐

    基于AKKA的后台应用开发手册

    #### 1 概述 ##### 1.1 前言 随着计算机硬件技术和网络技术的快速发展,计算机拥有的核心数量不断增多,分布式技术和集群技术的成熟使得一个应用程序可以被分解运行在多台独立的计算机上,这些计算机可能运行着...

    sparkSQL文档

    #### 一、SparkSQL概述 **1.1 什么是SparkSQL** SparkSQL是Apache Spark框架中的一个重要组件,主要用于处理结构化的数据。它为开发者提供了两个关键的功能:DataFrame API 和 SQL 查询语言的支持。DataFrame API ...

    Spark大数据分析:核心概念技术及实践

    - **RDD模型**: 弹性分布式数据集(Resilient Distributed Datasets, RDD)是Spark中最基本的数据抽象,支持各种转换操作(如map、filter、reduce等)以及行动操作(如count、collect等)。 ##### 2.3 Spark SQL - ...

    Spark 2.0入门+项目实战

    #### 1.1 Spark概述 Apache Spark是一种开源的大规模数据处理框架,它提供了一个比Hadoop MapReduce更为高级且易用的API,能够支持多种计算模式,包括批处理、交互式查询、流处理等。Spark的核心特性在于其内存计算...

    Hadoop 和 Spark 流行的大数据处理框架.docx

    - **Spark Core**:负责提供基本的分布式数据集抽象 Resilient Distributed Dataset (RDD),以及相关的依赖管理和容错机制。 - **Spark SQL**:使用户能够以 SQL 查询的方式处理结构化数据,并且可以与 RDD 结合使用...

    基于DL4J库CNN手写识别原理研究与实现_论文(001).doc

    相比之下,深度学习方法如CNN能够学习到更抽象、更具鲁棒性的特征,从而适应各种手写风格。 2.2 卷积神经网络(CNN) CNN的核心在于卷积层,其通过滤波器(或称卷积核)在输入图像上滑动,提取局部特征。池化层则...

    大数据技术分享 Spark技术讲座 结构化流中的连续处理 共20页.pdf

    #### 一、概述 在当前的大数据处理领域,Apache Spark凭借其高效的内存计算能力和丰富的生态系统成为了行业的佼佼者。Spark不仅支持批量处理,还支持实时流处理,后者通过Structured Streaming(结构化流)实现了对...

    大数据学习笔记

    - **定义**:RDD是Spark中最基本的数据抽象,是一个不可变的、分布式的数据集合。 - **特点**: - 支持容错恢复:通过血统信息追踪丢失的数据块。 - 支持缓存:可以将RDD持久化在内存中以加速后续的迭代计算。 ...

    SparkSQL原理和实践

    #### 一、SparkSQL概述 **SparkSQL**是Apache Spark的一个模块,用于处理结构化和半结构化数据。它提供了一个编程抽象称为DataFrame,并且充当了分布式数据集上的关系数据库查询引擎。SparkSQL的设计旨在简化大数据...

    大数据技术之Spark.docx

    #### 一、Spark概述 **1.1 什么是Spark** Spark是一种高性能、多功能且可扩展的大数据分析处理引擎。它最初由加州大学伯克利分校的AMPLab研发,于2009年问世,并在2010年开源。随着Spark社区的不断发展,它在2013...

    SparkSql技术

    - **hive/console原理**:概述了Hive控制台的工作原理及其与SparkSQL之间的交互。 **4.2 常用操作** - **查看查询的schema**:展示如何查看查询结果的schema信息。 - **查看查询的整个运行计划**:展示了如何查看...

Global site tag (gtag.js) - Google Analytics