scala的类与对象

xiaoxiao2021-02-27  213

一、类的定义

//在Scala中,类并不用声明为public。 //Scala源文件中可以包含多个类,所有这些类都具有公有可见性。 class Person { //用val修饰的变量是只读属性,有getter但没有setter //(相当与Java中用final修饰的变量) val id = "9527" //用var修饰的变量既有getter又有setter var age: Int = 18 //类私有字段,只能在类的内部使用 private var name: String = "唐伯虎" //对象私有字段,访问权限更加严格的,Person类的方法只能访问到当前对象的字段 private[this] val pet = "小强" } 二、构造器

注意:主构造器会执行类定义中的所有语句

/** *每个类都有主构造器,主构造器的参数直接放置类名后面,与类交织在一起 */ class Student(val name: String, val age: Int){ //主构造器会执行类定义中的所有语句 println("执行主构造器") try { println("读取文件") throw new IOException("io exception") } catch { case e: NullPointerException => println("打印异常Exception : " + e) case e: IOException => println("打印异常Exception : " + e) } finally { println("执行finally部分") } private var gender = "male" //用this关键字定义辅助构造器 def this(name: String, age: Int, gender: String){ //每个辅助构造器必须以主构造器或其他的辅助构造器的调用开始 this(name, age) println("执行辅助构造器") this.gender = gender } } /** *构造器参数可以不带val或var,如果不带val或var的参数至少被一个方法所使用, *那么它将会被提升为字段 */ //在类名后面加private就变成了私有的 class Queen private(val name: String, prop: Array[String], private var age: Int = 18){ println(prop.size) //prop被下面的方法使用后,prop就变成了不可变得对象私有字段,等同于private[this] val prop //如果没有被方法使用该参数将不被保存为字段,仅仅是一个可以被主构造器中的代码访问的普通参数 def description = name + " is " + age + " years old with " + prop.toBuffer } object Queen{ def main(args: Array[String]) { //私有的构造器,只有在其伴生对象中使用 val q = new Queen("hatano", Array("蜡烛", "皮鞭"), 20) println(q.description()) } }

三、对象

3.1单例对象

在Scala中没有静态方法和静态字段,但是可以使用object这个语法结构来达到同样的目的 1.存放工具方法和常量 2.高效共享单个不可变的实例 3.单例模式

import scala.collection.mutable.ArrayBuffer /** * Created by ZX on 2015/11/14. */ object SingletonDemo { def main(args: Array[String]) { //单例对象,不需要new,用【类名.方法】调用对象中的方法 val session = SessionFactory.getSession() println(session) } } object SessionFactory{ //该部分相当于java中的静态块 var counts = 5 val sessions = new ArrayBuffer[Session]() while(counts > 0){ sessions += new Session counts -= 1 } //在object中的方法相当于java中的静态方法 def getSession(): Session ={ sessions.remove(0) } } class Session{ } 3.2伴生对象

在Scala的类中,与类名相同的对象叫做伴生对象,类和伴生对象之间可以相互访问私有的方法和属性

class Dog { val id = 1 private var name = "itcast" def printName(): Unit ={ //在Dog类中可以访问伴生对象Dog的私有属性 println(Dog.CONSTANT + name ) } } /** * 伴生对象 */ object Dog { //伴生对象中的私有属性 private val CONSTANT = "汪汪汪 : " def main(args: Array[String]) { val p = new Dog //访问私有的字段name p.name = "123" p.printName() } } 四、apply方法

通常我们会在类的伴生对象中定义apply方法,当遇到类名(参数1,...参数n)时apply方法会被调用

object ApplyDemo { def main(args: Array[String]) { //调用了Array伴生对象的apply方法 //def apply(x: Int, xs: Int*): Array[Int] //arr1中只有一个元素5 val arr1 = Array(5) println(arr1.toBuffer) //new了一个长度为5的array,数组里面包含5个null var arr2 = new Array(5) } }

五、应用程序对象

cala程序都必须从一个对象的main方法开始,可以通过扩展App特质,不写main方法。

object AppObjectDemo extends App{ //不用写main方法 println("I love you Scala") }

六、代码示例

package com.heres.scala /** * 如果一个语言支持继承、封装、多态,我们就说这个语言支持面向对象;而面向对象语言的特征是 * 1.对象不需要关系消息从哪里来,也不关系消息到哪里去,而只关心消息处理本身,也就是说面向对象系统中 * 对象是弱耦合的,对象是消息(数据)驱动的; * 2.一个对象的行为不影响另一个对象的行为(一个对象挂掉了,另外一个对象不会随着它一起挂掉); * 3.面向接口编程; */ /** * 1.在scala中定义类是用class关键字; * 2.可以使用new Classname 的方式构建出对象; * 3.如果名称相同,则object中的内容都是class的静态内容,也就是说object中的内容class都可以在没有实例化的时候直接调用; * 正是因为可以在没有类的实例的时候去调用object中的一切内容,所以可以使用object中的特定方法来创建类的实例,而这个特定方法 * 就是apply方法; * 4.object中的apply方法是class对象生成的工厂方法,用于控制对象的生成; * 5.很多框架的代码一般直接调用抽象类的object的apply方法去生成类的实例对象: * 第一:其秘诀在于apply具有类的对象生成的一切生杀大权,抽象类是不可以直接实例化的,在apply方法中可以实例化抽象类的 * 子类,以Spark中的图计算为例,Graph是抽象的class,在object Graph中的apply方法实际上是调用了graph的子类 * GraphImpl来构建Graph类型的对象实例的,当然从Spark图计算的源码可以看出,GraphImpl的构造也是使用了object GraphImpl的 * apply方法的; * 第二:这种方式神奇的效应在于更加能够应对代码版本迭代或者修改的变化,这是更高意义的面向接口编程; * 6.object HelloObject 是class HelloObject 的伴生对象,class HelloObject可以直接访问object HelloObject中的一切内容 * ,而class HelloObject 是object HelloObject的伴生类,object HelloObject可以直接访问class HelloObject的一切内容。 * 7.在定义scala的class的时候可以直接在类名后面()里加入类的构造参数,此时apply方法中也必须有这些参数; * 8.scala可以在object中构造多个apply方法 * 9.scala中的很多集合都是使用apply构造的,例如,Array: * def apply[T : ClassTag](xs : T*):Array[T] = { * val array = new Array[T](xs.length) * var i =0 * for(x <- xs.iterator) { array(i) = x ; i += 1} * array * * } * */ class HelloObject(age : Int) { var name = "Spark" def sayHello = println("my name is "+name+", age is "+age) } object HelloObject { var number = 1 def main(args: Array[String]): Unit = { // val helloOOP = new HelloObject() val helloOOP = HelloObject(24) helloOOP.sayHello HelloObject().sayHello HelloObject(223) HelloObject(21) HelloObject(21) } def apply(age : Int): HelloObject = { println("my name is :"+number) number += 1 new HelloObject(age) } def apply(): HelloObject = { println("my name is :"+number) number += 1 new HelloObject(12) } }

转载请注明原文地址: https://www.6miu.com/read-9535.html

最新回复(0)