scala School笔记

特质和抽象类怎么选择

  1. 优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。
  2. 如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,而特质不行。例如,你不能说trait t(i: Int) {},参数i是非法的。

类型

一个使用泛型键和值的缓存的例子
trait Cache[K, V] {
  def get(key: K): V
  def put(key: K, value: V)
  def delete(key: K)
}

apply方法

当类或者对象有一个主要用途时,apply方法提供了一个很好的语法糖,可以让实例化对象看起来像是在调用一个方法

scala> FooMaker
res5: FooMaker.type = FooMaker$@27305e6

scala> object FooMaker {
  def apply() = ()=>println("1")}
     | defined object FooMaker

scala> FooMaker
res6: FooMaker.type = FooMaker$@ce5a68e

scala> FooMaker()
res7: () => Unit = <function0>

单例对象

单例对象用于持有一个类的唯一实例。通常用于工厂模式

object Timer {
  var count = 0

  def currentCount(): Long = {
    count += 1
    count
  }
}
scala> Timer.currentCount()
res0: Long = 1

模式匹配

  1. 匹配值
val times = 1

times match {
  case 1 => "one"
  case 2 => "two"
  case _ => "some other number"
}

使用守卫进行匹配
times match {
  case i if i == 1 => "one"
  case i if i == 2 => "two"
  case _ => "some other number"
}
  1. 匹配类型
def bigger(x:Any):Any={
  x match {
    case i:Int if i<0 => i-1
    case i:Int if i>=0 => i+1
    case d:Double if d<0.0 => d
    case text:String => text
    case _ => "fuck"
  }
}
  1. 匹配样本类成员
    使用样本类可以方便得存储和匹配类的内容。你不用new关键字就可以创建它们。
case class Calculator(brand: String, model: String)

def calcType(calc: Calculator) = calc match {
  case Calculator("HP", "20B") => "financial"
  case Calculator("HP", "48G") => "scientific"
  case Calculator("HP", "30B") => "business"
  case Calculator(ourBrand, ourModel) => "Calculator: %s %s is of unknown type".format(ourBrand, ourModel)
case Calculator(_, _) => "Calculator of unknown type"//与上句相同
}

变性 Variance

Scala的类型系统必须同时解释类层次和多态性

  1. 协变
scala> class Covariant[+A]
defined class Covariant

scala> val cv: Covariant[AnyRef] = new Covariant[String]
cv: Covariant[AnyRef] = Covariant@4035acf6

2.逆变

scala> class Contravariant[-A]
defined class Contravariant

scala> val cv: Contravariant[String] = new Contravariant[AnyRef]
cv: Contravariant[AnyRef] = Contravariant@49fa7ba

协变、逆变都是对应泛型参数,之前把泛型参数和函数参数搞混了。可以把协变逆变理解为一个壳子里套的某个参数支持协变逆变

class Animal { val sound = "rustle" }
class Bird extends Animal { override val sound = "call" }
class Chicken extends Bird { override val sound = "cluck" }

class Test[-R]{
  def sum(a:Test[Bird]) ="wuxiang"
val a = new Test
a.sum(new Test[Bird])
res24: String = wuxiang
a.sum(new Test[Animal])
res25: String = wuxiang
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,269评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,853评论 18 399
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,310评论 6 13
  • 面向对象主要针对面向过程。 面向过程的基本单元是函数。 什么是对象:EVERYTHING IS OBJECT(万物...
    sinpi阅读 1,124评论 0 4
  • 不知道你有没有这样的体会。 在一个夕阳西下的傍晚,你徘徊在悠长的走廊中,不知所措,就这样静静地走向远方。这个时候,...
    碎忆录阅读 265评论 0 1