企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
访问类的成员必须先`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 } } ```