scala java抽象理解_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()

: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()

: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 的模式匹配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值