天天看點

大資料Scala系列之類

大資料Scala系列之類

  1. 類的定義

Scala 通路修飾符基本和Java的一樣,分别有:private,protected,public。

如果沒有指定通路修飾符符,預設情況下,Scala 對象的通路級别都是 public。

私有(Private)成員

用 private 關鍵字修飾,帶有此标記的成員僅在包含了成員定義的類或對象内部可見,同樣的規則還适用内部類。

class Outer{

class Inner{
private def f(){println("f")}
class InnerMost{
    f() // 正确
    }
}
(new Inner).f() //錯誤           

}

(new Inner).f( ) 通路不合法是因為 f 在 Inner 中被聲明為 private,而通路不在類 Inner 之内。

但在 InnerMost 裡通路 f 就沒有問題的,因為這個通路包含在 Inner 類之内。

Java中允許這兩種通路,因為它允許外部類通路内部類的私有成員。

保護(Protected)成員

在 scala 中,對保護(Protected)成員的通路比 java 更嚴格一些。因為它隻允許保護成員在定義了該成員的的類的子類中被通路。而在java中,用protected關鍵字修飾的成員,除了定義了該成員的類的子類可以通路,同一個包裡的其他類也可以進行通路。

package p{

class Super{

protected def f() {println("f")}
}
class Sub extends Super{
    f()
}
class Other{
    (new Super).f() //錯誤
}           

類的定義示例:

//定義Point類,構造器帶有兩個參數

class Point(var x: Int, var y: Int) {

//無傳回值的類方法           

def move(dx: Int, dy: Int): Unit = {

x = x + dx
y = y + dy           
//沒有參數但是傳回值為String類型的重寫方法           

override def toString: String =

s"($x, $y)"           

//建立類的執行個體

val point1 = new Point(2, 3)

point1.x // 2

println(point1) // prints (2, 3)

構造器可以帶有預設值:

class Point(var x: Int = 0, var y: Int = 0){

...

val origin = new Point // x, y都取預設值0

val point1 = new Point(1)//x=1,y=0

println(point1.x) // prints 1

私有成員變量以及重新定義的Getter/Setter方法:

private var _x = 0

private var _y = 0

private val bound = 100

def x = _x

def x_= (newValue: Int): Unit = {

if (newValue < bound) _x = newValue else printWarning           

def y = _y

def y_= (newValue: Int): Unit = {

if (newValue < bound) _y = newValue else printWarning           

private def printWarning = println("WARNING: Out of bounds")

val point1 = new Point

point1.x = 99

point1.y = 101 // prints the warning

類定義中的其他細節:

//在Scala中,類并不用聲明為public。

//Scala源檔案中可以包含多個類,所有這些類都具有公有可見性。

class Person {

//用val修飾的變量是隻讀屬性的,隻帶getter方法但沒有setter方法

//(相當與Java中用final修飾的變量)

//字段必須初始化

val id = "1234"

//用var修飾的變量,預設同時有公開的getter方法和setter方法

var age: Int = 18

//類私有字段,有私有的getter方法和setter方法,隻能在類的内部使用

private var name: String = "王老五"

//對象私有字段,通路權限更加嚴格的,Person類的方法隻能通路到目前對象的字段

private[this] val hobby = "旅遊"

scala中,在實作屬性時你有如下四個選擇:

var foo: Scala自動合成一個getter和一個setter

val foo: Scala自動合成一個getter

由你來定義foo和foo_=方法

由你來定義foo方法

  1. 構造器

    注意:

1.主構造器會執行類定義中的所有語句

2.主構造器如果有參數直接放置在類名之後

class ConstructorDemo ( val id: Int ) { … }

3.主構造器變成私有的,可以像這樣放置private關鍵字:

class ConstructorDemo private ( val id: Int ) { … }

此時,使用者必須通過輔助構造器來構造Person對象

class ConstructorDemo {

private var var1 = ""

private var var2 = 0

//輔助構造器1

def this(var1:String) {

this()  //調用主構造器
this.var1 = var1           

//輔助構造器2

def this(var1:String, var2:Int) {

this(var1) //調用輔助構造器1
this.var2 = var2