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("小花")
}
val aCat = Cat()
|