0%

scala伴生类和伴生对象

scala伴生类和伴生对象

在之前的例子中也看到过有的文件中既声明了class又声明了object,这两个有什么区别呢,为什么main方法要在object中而不能和java一样在class中呢?

这是因为scala中将static关键字去掉了,采用了伴生类和伴生对象的概念来区分静态和非静态,在伴生类中的都是非静态的,而在伴生对象中声明的都是静态的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 伴生类
class Cat{
// _表示赋默认值
var name:String = _
var color:String = _
}

// 伴生对象
object Cat{
var count:Int = _

}


val cat= new Cat
cat.name = "小花"
cat.color = "黄白"
// 可以直接使用类来调用伴生对象中的字段和方法
Cat.count

class Cat编译后生成的java为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Cat
{
private String name;
private String color;

public static void count_$eq(final int x$1) {
Cat$.MODULE$.count_$eq(x$1);
}

public static int count() {
return Cat$.MODULE$.count();
}

public String name() {
return this.name;
}

public void name_$eq(final String x$1) {
this.name = x$1;
}

public String color() {
return this.color;
}

public void color_$eq(final String x$1) {
this.color = x$1;
}
}

object Cat编译成java之后为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public final class Cat$
{
public static final Cat$ MODULE$;
private static int count;

static {
MODULE$ = new Cat$();
}

public int count() {
return Cat$.count;
}

public void count_$eq(final int x$1) {
Cat$.count = x$1;
}

private Cat$() {
}
}
  • Scala中伴生对象采用object关键字声明,伴生对象中声明的相当于是java中的静态内容,可以通过伴生对象类名直接调用,伴生对象其实就是类的静态方法和成员的集合,伴生对象实现静态特性是依赖于 public static final MODULE$ 实现的
  • 伴生对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致
  • 从技术角度来讲,scala还是没有生成静态的内容,只不过是将伴生对象生成了一个新的类,实现属性和方法的调用
  • 伴生对象的声明应该和伴生类的声明在同一个源码文件中(如果不在同一个文件中会运行错误),但是如果没有伴生类,也就没有所谓的伴生对象了,所以放在哪里就无所谓了
  • 如果class A独立存在,那么A就是一个类, 如果object A独立存在,那么A就是一个”静态”性质的对象[即类对象], 在 object A中声明的属性和方法可以通过 A.属性和 A.方法来实现调用

在伴生对象中声明apply方法,可以实现类名(参数)方式创建对象实例

1
2
3
4
5
6
7
8
9
10
object Cat{
var count:Int = _

def apply():Cat = new Cat("小花")

}


// 不需要使用new来实例化,会自动调用apply()方法
val aCat = Cat()

欢迎关注我的其它发布渠道