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

自己采取的路线是和java对比来学习,方便理解scala,顺便也可以复习java。ヾ(◍°∇°◍)ノ゙

目录

1、Scala单例对象

2、Scala伴生对象 

3、apply方法

4、Java静态类、静态成员、静态方法说明


前言:函数式编程和面向对象编程区别

Scala是函数式编程:函数作为一个对象,能作为参数传递给其它参数,并且能作为函数的返回值

  • 面向对象调用:对象.方法                (点号调用)
  • 函数式调用:函数(参数)                  (括号调用)

scala> def add=(x:Int, y:Int)=>x+y //add是一个函数
add:(Int, Int)=>Int
scala> add(4, 5)
res2:Int = 9 //采用函数式调用
scala> add.apply(4, 5)
res3:Int = 9 //add也是对象,采用点号形式调用

Scala中函数式的调用可以转化成对象调用,同理对象调用也可以被转化成函数的调用。

val mycar = Car("BMW")
//是典型的函数式调用,在后台会自动转化成对伴生对象中apply方法的调用,从而创建一个对象
//当然前提是定义了apply方法

Python 语言提供 filter() 函数,很函数式:

filter(function, sequence)

filter() 函数的功能:对 sequence 中的 item 依次执行 function(item),将结果为 True 的 item 组成一个 List/String/Tuple(取决于 sequence 的类型)并返回。代码可以简化为:

divide_by_three = lambda x : True if x % 3 == 0 else False
selected_numbers = filter(divide_by_three, range(1, 11))

将 lambda 表达式放在语句中,代码简化到只需要一句话就够了:

selected_numbers = filter(lambda x: x % 3 == 0, range(1, 11))

 

1、Scala单例对象

单例对象就是java中的静态成员,注意:在scala中一切都为对象。

Scala单例对象是十分重要的,没有像在Java一样,有静态类、静态成员、静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员、它的方法都默认是静态的。

// 如果object的静态成员要被外界访问,则该成员不能被private修饰

package basic.runoob.advanced
/*
单例对象
Scala 没有静态方法或字段,可以用object语法定义结构,对象定义了类的单个实例。
对象的构造器在该对象第一次使用时被调用。
不能提供构造器参数。
作为存放工具函数或常量的地方。
高效地共享单个不可变实例。
 */
object Accounts {
   private var lastNumber = 0
  
   def newUniqueNumber(): Int = {
     lastNumber += 1
     lastNumber
       }

  def main(args: Array[String]): Unit = {
    val res1: Int = Accounts.newUniqueNumber() // 即访问了静态成员变量
    val res2: Int = Accounts.newUniqueNumber()
    println(res1)  // 1
    println(res2)  // 2   // 变量在累加
  }

}

2、Scala伴生对象 

  • 在Scala中,可通过类和类同名的“伴生”对象来达到静态方法的目的。 (java静态方法不用实例化对象,类.方法就可以调用了)
  • 类和它的伴生对象可以互访相问私有特性,它们必须存在于同一个源文件。
package basic.runoob.advanced
// 伴生对象

// Account类
class Account {
  // 访问伴生对象中的方法newUniqueNumber()
  val id: Int = Account.newUniqueNumber()

  private var balance = 0.0

  def deposit(amount: Double): Double = {
    balance += amount
    balance
  }

  def nowBalance: Double = balance;

}

// Account类的伴生对象 object Account
object Account {
  private var lastNumber = 0  // 静态变量 lastNumber

  private def newUniqueNumber() = {
    lastNumber += 1
    lastNumber
  }
}

//
object Main {
  def main(args: Array[String]): Unit = {
    val account = new Account
    println(account.deposit(1))  // 1.0
    println(account.id)  // 1.0
    println("=" * 10)

    val account1 = new Account
    println(account1.id)  // 2.0
    println(account1.deposit(10))  // 10.0
    println("=" * 10)

    println("a " + account.nowBalance + "; b " + account1.nowBalance) // a 1.0; b 10.0
  }
}
/*
1.0
1
==========
2
10.0
==========
a 1.0; b 10.0
 */

3、apply方法

个人理解:即类的构造方法。

val myStrArr = Array("BigData", "Hadoop", "Spark")
// 和我们之前学的java不一样,java中需要用到new来创建新的对象
val myStrArr = new String[]("BigData", "Hadoop", "Spark") // 这也不是规范的java语法

在Scala中不需要用new就可以直接创建新的对象,这里涉及到apply方法。当采用这种方式“()”声明一个数组的时候,Scala会自动调用Array这个类的伴生对象Array中的apply方法,从而创建一个数组对象。

apply方法调用:用括号传递给类实例或单例对象名一个或多个参数时,Scala会在相应的类或对象中查找方法名为apply且参数列表与传入的参数一致的方法,并用传入的参数来调用该apply方法。

package basic.runoob.advanced

// 文件名为Accountapply.scala
// 即scala和java不同,不需要文件名和类名一致

/*
一般在伴生对象中定义apply方法
常用于初始化操作或创建单例对象
在生成这个类的对象时,就省去了new关键字
在遇到Object(参数1,参数2,……,参数n)时就会自动调用apply()方法
 */

class Student private (val sno: Int, val name: String){

  override def toString: String = {
    "sno " + sno + " name " + name
  }
}


object Student {
  private var sno = 0

  private def newSno = {
    sno += 1
    sno
  }


  def apply(name: String): Student = {

    println("call apply method...")
    new Student(newSno, name)
  }
}

// 程序入口Main
object StudentMain extends App {
  // no new
  val student1 = Student("Yezhiwei") // 在生成Student类的对象时,省去了new关键字
  println(student1.toString)

  println("*" * 10)
  val student2 = Student("Yezhiwei")
  println(student2.toString)
}

/*
call apply method...
sno 1 name Yezhiwei
**********
call apply method...
sno 2 name Yezhiwei
 */

在Scala中,我们把所有类的构造方法以apply方法的形式定义在它的伴生对象当中,这样伴生对象的方法就会自动被调用,调用就会生成类对象。

pandas apply() 函数用法 和pandas中的apply有些不一样,但我个人理解核心思想都是“自动”。

pandas 的 apply() 函数可以作用于 Series 或者整个 DataFrame,功能是自动遍历整个 Series 或者 DataFrame, 对每一个元素运行指定的函数。( df 数据.apply(要进行的操作) )

 

4、Java静态类、静态成员、静态方法说明

有空再说吧。。。(*^▽^*)

 

参考:

Scala快速入门-6-单例对象及伴生对象 - 极乐君的文章 - 知乎

4.Scala语言基础之面向对象编程 -- 对象(apply方法) - 紅燴小牛膝的文章 - 知乎

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值