Scala 類相關
終于來到面向?qū)ο蟮牡胤搅酥急穑m說函數(shù)式編程是 Scala 的特性患朱,讓人們覺得 Scala 是更好的 Java译蒂。但是在架構(gòu)層面上一直提倡著:小處用函數(shù)式編程牢酵,大處用面向?qū)ο缶幊獭?/p>
從這篇筆記開始荐类,會記錄類的相關內(nèi)容。由于類相關的內(nèi)容比較多茁帽,我可能會整理幾篇文章來寫玉罐。
1. 構(gòu)造器
在 java 中定義一個簡單的用戶類,以及構(gòu)造函數(shù)
public class User {
private String name;
private String password;
public User(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
然而在 Scala 中潘拨,只需一代碼即可跟上面的 Java 代碼等價吊输。
scala> class User(var name:String,var password:String)
defined class User
然后創(chuàng)建一個 User 對象。
scala> val tony = new User("tony","123456")
tony: User = User@6a0659ac
也可以用 case 類來推斷出構(gòu)造方法的參數(shù)都是val類型的
scala> case class ImmutableUser(name:String,password:String)
defined class ImmutableUser
scala> val user = ImmutableUser("tony","123456")
user: ImmutableUser = ImmutableUser(tony,123456)
稍后铁追,就會講到case class季蚂。
2. 單例對象、伴生對象、Case Class扭屁、Trait
2.1 單例對象
在Scala學習筆記(二)中算谈,講述過Scala 中沒有靜態(tài)修飾符 static,在 object 下的成員全部都是靜態(tài)的料滥,而且 object 不能提供構(gòu)造器參數(shù)然眼。
那么,今天再補充一下葵腹,以 object 關鍵字定義的對象是一個單例對象高每。
先上一段代碼。
scala> object Singleton {
| def test() = println("test singleton")
| }
defined object Singleton
scala> Singleton.test()
test singleton
經(jīng)過查看 class 文件獲取它的源碼践宴,Singleton 生成了一個懶漢模式的單例類鲸匿。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import scala.Predef.;
public final class Singleton$ {
public static final Singleton$ MODULE$;
static {
new Singleton$();
}
public void test() {
.MODULE$.println("test singleton");
}
private Singleton$() {
MODULE$ = this;
}
}
2.2 伴生對象
如果在類中聲明了與該類相同的名字的 object 則該object 是該類的“伴生對象”。
相對于伴生對象阻肩,單獨的 object 對象是獨立對象(Standalone Object)带欢。他們的主要用途是可以用于工具類,或者定義 Scala 程序的入口等等烤惊。
來看一個伴生對象和伴生類使用的例子洪囤。
/**
* Created by tony on 2017/2/20.
*/
class User(var name:String,var age:Int) {
def greet: Unit = {
println("hi, My name is "+name)
}
override def toString: String = {
"name is "+ name + ", age is " + age
}
}
object User {
def addAge(u: User) = u.age +1
}
object Main extends App {
//伴生對象可以引用類的私有變量
val user = new User("Tony",20)
println(user.age) // 20
user.age = User.addAge(user)
//類可以引用伴生對象的私有變量
user.greet // hi, My name is Ton
println(user) // name is Tony, age is 20
}
2.3 Case Class
case class 跟普通 class 的區(qū)別在于
- 初始化的時候不需要 new
- 自動創(chuàng)建伴生對象
- 默認是可以序列化的,實現(xiàn)了 Serializable
- 構(gòu)造函數(shù)的參數(shù)都是 val 類型的
- 支持模式匹配撕氧。
- 實現(xiàn)自己的 toString瘤缩、hashCode、copy伦泥、equals 方法
scala> case class User(name:String,age:Int)
defined class User
scala> val tony = User("Tony",20)
tony: User = User(Tony,20)
scala> tony.age = 21
<console>:14: error: reassignment to val
tony.age = 21
^
模式匹配剥啤,后面的文章會講到。
2.4 Trait
Scala 不提供接口不脯,而提供類似接口的 Trait 府怯,跟接口不同的是 Trait 可以寫方法的實現(xiàn)。這一點跟 Java 8 接口的默認方法很相似防楷。
scala> trait Fly {
| def fly()
| }
defined trait Fly
scala> trait Swim {
| def swim()
| }
defined trait Swim
scala> class Duck extends Swim {
| def swim() {
| println ("duck can swim")
| }
| }
defined class Duck
scala> class Swan extends Swim with Fly {
| def swim() {
| println ("swam can swim")
| }
|
| def fly() {
| println ("swam can fly")
| }
| }
defined class Swan
scala> val swam = new Swan()
swam: Swan = Swan@1d0d6318
scala> swam.swim()
swam can swim
scala> swam.fly()
swam can fly
scala>
定義兩個Trait牺丙,“飛”和“游泳”。再定義兩個類复局,“鴨子”和“天鵝”冲簿。鴨子會游泳,而天鵝既會游泳亿昏,也會飛峦剔。
對于 Trait 不止一個的類的時候,可以用 with
關鍵字來添加額外的 Trait角钩。
例如:
extends Trait1 with Trait2 with Trait3
3. 繼承
像 Java 一樣吝沫,Scala 只支持單一繼承呻澜,而不是多重繼承。
總結(jié)
本篇內(nèi)容只是 Scala 類相關內(nèi)容的開頭惨险,后續(xù)會陸續(xù)整理羹幸。
先前的文章:
Scala學習筆記(三)
Scala學習筆記(二)
Scala學習筆記(一)