Scala学习笔记(五) 抽象类以及类中的一些语法糖

1. 抽象类

Scala 的抽象类跟Java的一样,不能被实例化。

1.1抽象字段

抽象类中,变量不使用就无需初始化,可以等到子类继承时再进行初始化。

scala> abstract class Animal {
     |    val name:String // 抽象字段,没有带初始值
     | }
defined class Animal

scala> class Bull extends Animal {
     |   val name = "bull"
     | }
defined class Bull

scala> class Bull2 extends Animal {
     |   override val name = "bull2" // 加上override更符合标准
     | }
defined class Bull2

1.2抽象方法

在抽象类中,抽象方法无需使用(也不能)用abstract进行修饰。

一个方法只要是没有它的实现(没有等号或没有方法体),它就是抽象的,在子类中覆写或者覆写接口中的非抽象方法(方法有具体实现)要使用override关键字。

scala> abstract class Teacher{
     |    var name:String
     |    var age:String
     |    def teach
     | }
defined class Teacher

scala> class TeacherForMath extends Teacher {
     |    var name = "Tony"
     |    var age = "30"
     |    override def teach = println("teaching Math")
     | }
defined class TeacherForMath

scala> val teacher = new TeacherForMath()
teacher: TeacherForMath = TeacherForMath@27ddd392

scala> teacher.teach
teaching Math

1.3抽象类型

Scala 中的类型成员也可以是抽象的。
比如,在Trait中,你可以让类型成员保持抽象。

scala> trait Foo {
     |   type T;
     |   val x:T;
     |   def getX:T = x
     | }
defined trait Foo

scala> (new Foo{type T = Int; val x = 123}).getX
res0: Int = 123

scala> (new Foo{type T = String;val x = "hello tony"}).getX
res1: String = hello tony 

2. 类中的apply()

在 Scala 的类中,apply() 可以看作是一个语法糖,它分为两种方式:object和class中的用法。

2.1 常见的 apply() 用法

借用一个经典的例子。

scala> class Foo{}
defined class Foo

scala> object FooMaker {
     |   def apply() = new Foo
     | }
defined object FooMaker

scala> val newFoo = FooMaker()
newFoo: Foo = Foo@39ba5a14

在调用 FooMaker() 时,触发了apply(),所以生成了一个新的Foo对象。

再来看一个例子。

scala> class Bar {
     |   def apply() = println("this is bar")
     | }
defined class Bar

scala> val bar = new Bar
bar: Bar = Bar@59e84876

scala> println(bar())
this is bar
()

scala> bar()
this is bar

这次是在调用bar()时,触发了apply(),打印了this is bar

由此,可以总结:

  • object类是单例,不能进行new的实例化。在调用类名()时,便会触发调用该object中的apply()。如果object类中没有apply(),这样调用会报错。
scala> object FooMarker2 {
     |   def apply2() = new Foo
     | }
defined object FooMarker2

scala> val newFoo2 = FooMarker2()
<console>:13: error: FooMarker2.type does not take parameters
       val newFoo2 = FooMarker2()
                               ^
  • 在类中,创建 val bar = new Bar 之后,调用 bar() 便会触发该类的apply()。同样,class中没有定义apply(),这样调用也是会报错的。
scala> class Bar2 {
     |   def apply2() = println("this is bar2")
     | }
defined class Bar2

scala> val bar2 = new Bar2
bar2: Bar2 = Bar2@7f416310

scala> bar2()
<console>:14: error: Bar2 does not take parameters
       bar2()
           ^

2.2 伴生类和伴生对象中的apply()

把刚才的内容结合起来,顺便回忆一下上一篇中的伴生类和伴生对象。

/**
  * Created by tony on 2017/2/28.
  */
class ApplyTest {

  def apply() = println("This is called by class!")

  def haveATry: Unit = {
    println("have a try on apply")
  }
}

object ApplyTest {

  def apply() = {
    println("This is called by companion object")
    new ApplyTest
  }
}

object ApplyOperation {
  def main(args: Array[String]) {

    val a1 = ApplyTest()   //object 的 apply() 使用

    a1.haveATry
    a1() // class 中 apply()使用

    println("------------------")

    val a2 = new ApplyTest
    a2.haveATry
    a2() // class 中 apply()使用
  }
}

调用的结果如下:

This is called by companion object
have a try on apply
This is called by class!
------------------
have a try on apply
This is called by class!

Process finished with exit code 0

最后,除了在类中可以使用apply(),在function中也可以使用apply(),因为在 Scala 中函数即对象,后面的笔记会进行总结。

3. 类中的update()

update() 也可以看作是 Scala 的语法糖。
使用 update() 时,等号右边的值会作为 update 方法的最后一个参数。

scala> class User(var name:String,var password:String) {
     |    def update(name:String,password:String) = {
     |       println(s"changing use of $name and $password")
     |       this.name = name
     |       this.password = password
     |    }
     | }
defined class User

scala> val tony = new User("tony","123456")
tony: User = User@6d868997

scala> tony.password
res17: String = 123456

scala> tony.update("tony","abcdefg")
changing use of tony and abcdefg

scala> tony.password
res19: String = abcdefg

scala> tony("tony") = "abcdefg"
changing use of tony and abcdefg

scala> tony.password
res21: String = abcdefg

在这里,tony.update("tony","abcdefg") 和 tony("tony") = "abcdefg" 这两句话是等价的。前一种方法比较中规中矩,后一种方法更加简洁。

总结

本篇笔记仍然是整理类相关的内容,主要是抽象类、类中的apply()和update()。apply()和update()都是语法糖,加以合适的应用,能得到可读性极强的代码。

下一篇笔记会整理 Scala 的模式匹配。

先前的文章:
Scala学习笔记(四) 类的初步
Scala学习笔记(三)
Scala学习笔记(二)
Scala学习笔记(一)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,158评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,600评论 1 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,785评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,655评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,075评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,002评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,146评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,918评论 0 211
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,671评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,838评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,318评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,636评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,343评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,187评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,982评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,126评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,934评论 2 279

推荐阅读更多精彩内容

  • Scala学习笔记: 1.1 scala的基础语法 声明与定义(赋值):声明变量时可以指定类型,不指定也可以自动识...
    哎哟喂喽阅读 539评论 0 2
  • scala文档 包含内容 1基础 2控制结构和函数 3数组相关操作 4映射和元组 5类 6对象 7.包和引入(x)...
    zlcook阅读 961评论 0 3
  • scala学习笔记 第2章 变量和数据类型 基本数据 scala的核心数据为四种 :字面量、值、变量、类型 值使...
    485b1aca799e阅读 2,081评论 0 1
  • 这篇讲义只讲scala的简单使用,目的是使各位新来的同事能够首先看懂程序,因为 scala 有的语法对于之前使用习...
    MrRobot阅读 2,869评论 0 10
  • 成长的路上,你我都像被打了一针的查理。突然间对事物有了自己的理解,懂得质疑老师和权威做出自己的判断。 有一天,当你...
    小v木阅读 614评论 0 0