訪問類的成員必須先`new`,訪問單例對象的成員只能是`ObjectName.成員`。而伴生即可以先`new`,再訪問成員;也可以直接`伴生名.成員`來調用伴生的成員。
<br/>
**1. 定義伴生的限制條件**
* 在同一個`.scala`文件中
* `class ClassName`和`object ObjectName`的ClassName與ObjectName必須是同名
**2. 伴生的特點**
* 一旦建立伴生關系,伴生對象與伴生類可相互訪問私有成員。
* 在伴生類中訪問伴生對象的成員,`ObjectName.成員`;在伴生對象中訪問伴生類的成員,`實例.成員`。
* 伴生對象主要為伴生類提供一種靜態成員訪問的途徑。
**3. 定義伴生**
在同一個 *`Point1.scala`* 文件中定義伴生
```scala
// 定義伴生類
class Point1(var x:Int, var y:Int) {
def this() = {
this(0, 0)
}
def move(dx:Int, dy:Int):Unit={
x = x + dx;
y = y + dy;
}
// 在伴生類中訪問伴生對象成員
Point1.name
}
// 定義伴生對象
object Point1 {
private var name:String = "zhangsan"
var age:Int = 10000
// 必須定義apply方法
def apply(x: Int, y: Int): Point1 = new Point1(x, y)
def main(args: Array[String]): Unit = {
val point1 = Point1(10, 20) // 不需要new是因為在apply方法中已經new好了
// val point1 = Point1.apply(10, 20) 與 Point1(10, 20) 是一樣的效果,但是依然需要定義apply方法
// 在伴生對象中訪問伴生類的成員
point1.x
point1.move(30, 30)
}
}
```
在其他類或對象中訪問伴生:
```scala
import org.example.oop.Point1
object App{
def main(args: Array[String]): Unit = {
Point1.age // 訪問的是伴生對象中非private的字段
val point1 = Point1(10, 20)
point1.move(20, 20) // 訪問的是伴生類中非private的成員
point1.x
}
}
```
在 Scala 中,apply()方法有著特殊的含義。對于函數來說即調用函數自身。例如:
```scala
val f = (x: Int) => x + 1
f.apply(1)
f(1) //等價于 f.apply(1)
```
<br/>
**4. 伴生對象繼承伴生類**
當伴生對象繼承伴生類后,伴生對象就將伴生類的所有成員繼承了,即使是private成員,所以訪問伴生類或伴生對象的成員的時候可以直接`伴生名.成員`
*`Point1.scala`*
```scala
package org.example.oop
// 定義伴生類
class Point1(var x:Int, var y:Int) {
def this() = {
this(0, 0)
}
def move(dx:Int, dy:Int):Unit={
x = x + dx;
y = y + dy;
}
// 在伴生類中訪問伴生對象成員
Point1.name
}
// 定義伴生對象并繼承伴生類
object Point1 extends Point1 {
private var name:String = "zhangsan"
var age:Int = 10000
// 必須定義apply方法
def apply(x: Int, y: Int): Point1 = new Point1(x, y)
def main(args: Array[String]): Unit = {
Point1.x
Point1.move(30, 30)
}
}
```
在其他對象或類中訪問:
```scala
package org.example
import org.example.oop.Point1
object App{
def main(args: Array[String]): Unit = {
// 訪問方式1
val point1 = Point1(10, 20)
point1.move(20, 20) // 訪問的是伴生類中非private的成員
point1.x
// point1.age 報錯
// 訪問方式2
Point1.x
Point1.move(20, 20)
Point1.age
}
}
```
- Scala是什么?
- Scala特性
- 開發環境搭建
- 環境搭建
- windows下的環境搭建
- IntelliJ IDEA環境搭建
- Scala關鍵字
- Hello, World
- 數據類型
- 數據類型
- 數據類型層次結構
- 字面量
- Null類型
- Nothing類型
- Unit類型
- 變量與常量
- type定義類型別名
- 字符串插值器
- 條件控制
- 循環控制
- 數組
- 元組
- 集合
- 集合分類
- List常用操作
- Set常用操作
- Map常用操作
- 函數
- 函數聲明與調用
- 函數與方法的區別
- 函數注意事項
- 匿名函數
- 可變參數
- 高階函數
- 中置表達式
- 函數嵌套
- 函數科里化
- 隱式參數
- 隱式函數
- 閉包
- 類和對象
- Java與Scala的比較
- 有關類與對象概念
- 類
- 類的定義和調用
- 類的繼承
- 抽象類
- 單例對象
- 伴生對象和伴生類
- 特質
- 定義特質
- 混入特質
- 抽象類與特質的選擇
- 自身類型
- 依賴注入
- this別名
- 樣例類
- 枚舉類
- 泛型類
- 包與包對象
- 模式匹配
- 基本語法
- 匹配模式
- 偏函數
- 注解
- 運算符
- 正則表達式
- 隱式類
- 異常處理
- 高級類型
- 結構類型
- 復合類型