访问类的成员必须先`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别名
- 样例类
- 枚举类
- 泛型类
- 包与包对象
- 模式匹配
- 基本语法
- 匹配模式
- 偏函数
- 注解
- 运算符
- 正则表达式
- 隐式类
- 异常处理
- 高级类型
- 结构类型
- 复合类型