虽然java一直声称自己是完全面向对象的语言,但一直以来都被很多人所质疑,其中java的静态成员函数就是主要的“罪魁祸首”。由于java中保留了静态方法的调用,导致其编程模式依然有过程式编程的可能,尤其是在静态方法被滥用的当下(一个顽固的面向过程程序员完全可以将他的过程思维用一大推静态方法实现,而class仅仅只是个空有其表的外壳而已)
所以在scala中,设计者摒弃了static关键字,宣称自己是完全面向对象的,似乎更有说服力。。。
但是我们在编程中有时确实需要用到一般功能性函数,例如工具函数、工厂设计模式等。怎么办呢?compaion object(伴生对象)闪亮登场!
什么是compaion object?很简单,(一般在同一个文件中)同时定义了一个class,以及与这个class同名的object,那么这个object就是这个class的伴生对象,这个class就是这个object的伴生类。。。是不是有点拗口,其实就可以看成命运共同体啦╮(╯▽╰)╭
以class A,object A为例,有了compaion object之后,就可以将object A的作用域理解为静态域,在该object A中定义的任何变量、常量、方法X,均可以在对应的访问权限下通过A.X直接访问;这两个命运共同体的内部特殊点在于可以访问彼此的私有成员,class A里可以通过A.X访问object的私有成员,而object中可以访问某个class A对象的私有成员a.XX。注意这里理解容易出错,object A虽然是class A的伴生对象,但它不是A的对象,所以它本身不具备A的一切成员和方法,他只是一个特殊的作用域,因此它内部不能直接访问class A的成员变量。
talk is cheap, show you my code~
package basic.test class Cat{ private var name = "Tom" private var age = 0 def run = println("A cat " + name + " is running...") def classify = println("It is a " + Cat.category)//注意这里访问了object Cat的私有成员 override def toString = "Cat{name:" + name + ",age:" + age + "}" } object Cat{ private val category = "Animal"//如果这里试图在函数中直接访问name、age,都报错,例如//def createCat = {// println(name + age)//}//报错无法找到name和age def createCat = { var res = new Cat res.name = "Created Tom"//注意这里直接访问修改class Cat的私有成员变量 res.age = 1//注意这里直接访问修改Cat的私有成员变量 res
} }
scala> import basic.test.Cat
import basic.test.Cat
scala> var a = new Cat a: basic.test.Cat = Cat{name:Tom,age:0} #这里直接调用Cat的工厂方法 scala> Cat.createCat res0: basic.test.Cat = Cat{name:Created Tom,age:1} scala> a.classify It is a Animal
上边的例子一目了然,如果你还没看懂,去看看本教程前边的内容吧~
原文地址:https://www.cnblogs.com/wangyalou/p/9568714.html