Scala(5)

来源:互联网 发布:淘宝推广方式 编辑:程序博客网 时间:2024/05/16 13:54

Traits

  • 这一章介绍了Scala面向对象编程中一个非常重要的结构吧:Trait。Trait在英文的解释是:A distinguishing characteristic or quality。这个词的意思就很好解释了Trait在Scala中的作用:用来描述Object的一些特性,但是这特性又不在继承关系下的,即使用继承来表示这种关系很牵强,所以需要Trait。

  • Trait的使用有点类似于Class,可以使用extend或者with关键字来使用。在Trait中定义了method和field后,那么使用这个trait的类就会有对应的方法。

  • Trait主要提供两种使用方法:1. turning a thin interface into a rich one 2. providing stackable modifications to classes

  • A trait also defines a type。如:有一个trait:Philosophical以及一个Class:Frog。Frog使用了Philosophical,那么根据多态的原则,就可以把已该车Frog类型的变量赋值给一个Philosophical型的变量

  • 事实上,一个trait基本上和一个class没什么区别,在class里可以做的事情基本上都可以在trait中做到,除了有两点例外:1. A trait cannot have any “class parameter” 2. The other difference is that whereas in classes, super calls are statically bound, in traits, they are dynamically bound. 事实上,正是因为这种 dynamically bound 特性,所以allowing traits to work as stackable modifications

  • 本章还介绍了一个比较广泛使用的Trait:Ordered trait。使用Ordered trait要注意需要传递一个 type parameter ,另外 the Ordered trait does not define equals for you, because implementing equals in terms of compare requires checking the type of the passed object, and because of type erasure, Ordered itself cannot do this test.

  • stackable modifications主要分为了两个方法:modifications以及stackablemodifications指的是traits不定义类,只是在这个基础上提供修改类属性的方法。stackable是指不同的trait提供了不同的修改方法,而类可以“mixin”许多不同的trait,达到stackable的效果

  • stackable modifications需要用到关键字abstract override,and it means that the trait must be mixed into some class that has a concrete definition of the method。这个其实就是实现了abstract override方法的类才可以使用这个trait

  • 当一个类使用到了多个trait,那么the order of mixins is significant – the method called is determined by a linearization of the classes and traits that are mixed into a class。 概括来说,就是 traits further to the right take effect first

  • linearization意思就是:When you instantiate a class with new, Scala takes the class and all of its inherited classes and traits and puts them in a single, linear order. Then, whenever you call super inside one of those classes, the invoked method is the next one up the chain. If all of the methods but the last call super, the net result is stackable behavior.

  • 来看看书上这个例子,有如下定义:

class Animaltrait Furry extends Animaltrait HasLegs extends Animaltrait FourLegged extends HasLegsclass Cat extends Animal with Furry with FourLegged

示例
上图展示了Cat这个类的继承关系以及线性化。白色箭头表示继承关系,黑色箭头则表示线性化。线性化的计算结果是从后往前构造的,如下:

a. 首先计算Animal的线性化,因为Animal没有直接使用到任何的trait或者直接显示继承任何类,那么它的线性化结果如下:

Animal -> AnyRef -> Any

b. 接着计算Furry的线性化结果,但是这次 all classes that are already in the linearization of Animal are left out now, which means that each class appears only once in Cat’s linearization. 结果如下:

Furry -> Animal -> AnyRef -> Any

c. 按照如此计算下去,最终结果就是:

Cat -> FourLegged -> HasLegs -> Furry -> Animal -> AnyRef -> Any

Packages and Imports

  • 这一章主要介绍如何将代码用packages的形式包装,如何通过access modifiers来控制 visibility of definitions

  • Scala有两种组织package name的形式:第一种和Java类似,在文件第一行写明属于哪个package;第二种就是和C#类似,写成namespace形式(任使用关键字package)。不过,与Java不同的,Scala’s packages truly nest.

  • Scoping rules同样也适用于packages – packages in an inner scope hide packages of the same name that are defined in an outer scope. 另外,Scala还有个特殊的package:root_,every top-level package you can write is treated as a member of package *_root_

  • Scala与Java对比,在imports上有三点不同:

    1. may appear anywhere

    2. may refer to objects(singleton or regular) in addition to packages

    3. let you rename and hide some of the imported members

  • 还要几点有关import的细节:

    1. A renaming clause is always of the form “ => ”

    2. A clause of the form “ => _” excludes from the names that are imported

    3. Scala不再使用 * 作为import 通配符,而是换做了 _

  • Scala adds some imports implicitly to every program,主要是下面这三条语句(顺序也很重要):

import java.lang._import scala._import Predef._

而且, later imports overshadow earlier ones.

  • Access modifiers在Scala中有着更严格的限制:

    1. 如果没有显示使用private或者protected关键字,那么可见性就是public

    2. 使用了private关键字,那么这个可见性只有在这个类起作用。不允许an outer class access private members of its inner classes

    3. 使用了protected关键字,那么这个可见性只有在这个类以及它的子类起作用,accesses are not possible from other classes in the same package

  • 当然,Scala还提供了另外的机制,which enables you to express Java’s accessibility notions – A modifier of the form private[X] or protected[X] means that access is private or protected “up to” X, where X designates some enclosing package, class or singleton object

  • 不过,有个比较难懂的概念,就是private[this] – A defintion labeled private[this] is accessible only from within the same object that contains the definition。意思就是: Any access to member labeled with private[this] must not only be within the class, but it must also be made from the very same instance of that class。这里我还是没理解这句话是什么意思?如何保证access是 made from the very same instance of that class呢?

  • 对于companion class和companion object有如下规定: A class shares all its acces rights with its companion object and vice versa. In particular, an object can access all private members of its companion class, just as a class can access all private members of its companion object

0 0