scala成长之路(4)compaion object——伴生对象的使用

虽然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

时间: 2024-11-01 22:06:10

scala成长之路(4)compaion object——伴生对象的使用的相关文章

scala成长之路:问题记录

scala成长之路(5)问题记录 还是在看scala sdk源码的时候,有很多问题要考自己慢慢摸索,这里做个记录. 一. 隐式转换的作用域? 隐式转换需要三个因素 1. 己方(当前对象) 2. 转换函数 3. 对方(转换的目标类) 这三个需要在同一个作用域内才能生效吗?举个简单的例子,依然是java HashSet隐式转换为scala Set(可以参看本系列(3)),我们只是在要用到转换的文件里写了一行: import scala.collection.JavaConverters._ 也就是说

在scala中,类和它的伴生对象可以相互访问对方的私有对象

class Person {   private var _age = 2   def age_=(num: Int) = this._age = num   def age = _age   def printObj { println(s"I can see ${Person.obj}") } } object Person {   // access the private class field 'age'   def double(p: Person) = p._age * 

scala成长之路(2)对象和类

scala提供了一种特殊的定义单例的方法:object关键字 scala> object Shabi{ | val age = 0 | val name = "shabi" | def say = { | println("hello, I am a shabi") | } | }defined object Shabi scala> Shabi.sayhello, I am a shabi object定义的单例可以类比于java中的静态元素,也类似于

scala成长之路(6)函数入门

众所周知,scala作为一门极客型的函数式编程语言,支持的特性包括: 函数拥有"一等公民"身份: 支持匿名函数(函数字面量) 支持高阶函数 支持闭包 部分应用函数 柯里化 首先需要指出,在scala中有方法和函数对象两种形态,方法即是通过def关键字定义的函数,而函数对象则是通过将方法转换而来,或lambda赋值而来. 1. 从"一等公民"说起 很多稍微了解过函数式编程的人可能都听说过"一等公民"这种说法,但却很少有人能明明白白地说出究竟什么是&

scala成长之路(7)函数进阶——可能是史上最浅显易懂的闭包教程

由于scala中函数内部能定义函数,且函数能作为函数的返回值,那么问题来了,当返回的函数使用了外层函数的局部变量时,会发生什么呢?没错,就产生是闭包. 关于闭包的解释网上一大堆,但基本上都是照葫芦画瓢,一个模子刻出来的,说来说去都只讲了"内部函数引用外层函数的局部变量"这个刻板的定义,根本没降到精髓.精髓是什么?且看我一句话给你讲清楚: 闭包就是外层函数函数的对象,外层函数就是闭包的构造函数! 怎么样,是不是摸不着头脑?其实是这样,我们使用闭包的目的并不是为了引用外层函数的局部变量,这

快学Scala 第九课 (伴生对象和枚举)

Scala没有静态方法和静态字段, 你可以用object这个语法结构来达到同样的目的. 对象的构造器只有在第一次被使用时才调用. 伴生对象apply方法: 类和它的伴生对象可以互相访问私有特性,他们必须存在于同一个源文件. 类中要访问类的伴生对象中成员,需要通过类.成员调用. class Account private (val id: Int, initialBalance: Double){ } object Account { def apply(initialBalance: Doubl

scala学习手记15 - 独立对象和伴生对象

上一节中的单例对象MarkerFactory 就是一个独立对象的例子.尽管它管理着Marker类,但是它并没有关联到任何类上. scala也可以创建关联到类上的对象.这样的对象同类共享同一个名字,这样的对象称为伴生对象,对应的类就称为伴生类.在scala里,类和伴生对象没有界限,它们互相可以访问彼此的private 方法和private 属性.下面使用伴生对象重写了Marker: class Marker private(val color: String) { println("Creatin

python成长之路第三篇(1)_初识函数

目录: 函数 1.为什么要使用函数 2.什么是函数 3.函数的返回值 4.文档化函数 5.函数传参数 文件操作(二) 1.文件操作的步骤 2.文件的内置方法 函数: 一.为什么要使用函数 在日常写代码中,我们会发现有很多代码是重复利用的,这样会使我们的代码变得异常臃肿,比如说: 我们要写一个验证码的功能 例子: 比如说我们要进行一些操作,而这些操作需要填写验证码 验证码代码:  1 import random   2 number_check = ''   3 for i in range(0,

【Scala】单例对象与伴生对象

Scala的单例对象 Scala不能定义静态成员,而是代之定义单例对象(singleton object).以object关键字定义. 对象定义了某个类的单个实例,包含了你想要的特性: object Accounts{ private var lastNumber = 0 def newUniqueNumber() = { lastNumber += 1; lastNumber} } 当你在应用程序中需要一个新的唯一账号时,调用Account.newUniqueNumber()即可. 对象的构造