scala 类,伴生对象
1.属性的定义
编写一个PersonS类,并在其中定义一些属性,通过PersonS.scala 编译后的情况查看,可以知道不同修饰符修饰的属性分别会生成什么方法(set,get)
package com.jason.qianfeng
class Persons {
//val修饰的属性系统自动生成get方法
val id: String = "1234"
//var 修饰的属性系统会自动生成set 和 get 方法
var name:String = ""
// private var修饰的属性系统会自动生成private set 和 get 方法
//private 修饰的属性属于类私有的
private var gender:Int = 0
//private[this]修饰的属性系统不生成set 和get 方法
//private[this]修饰的属性属于对象私有
private[this] var age:Int = 0
}
编译后用jd-gui 反编译查看
package com.jason.qianfeng; import scala.reflect.ScalaSignature; @ScalaSignature(bytes="\006\001m2A!\001\002\001\023\t9\001+\032:t_:\034(BA\002\005\003!\t\030.\0318gK:<'BA\003\007\003\025Q\027m]8o\025\0059\021aA2p[\016\0011C\001\001\013!\tYa\"D\001\r\025\005i\021!B:dC2\f\027BA\b\r\005\031\te.\037*fM\")\021\003\001C\001%\0051A(\0338jiz\"\022a\005\t\003)\001i\021A\001\005\b-\001\021\r\021\"\001\030\003\tIG-F\001\031!\tIBD\004\002\f5%\0211\004D\001\007!J,G-\0324\n\005uq\"AB*ue&twM\003\002\034\031!1\001\005\001Q\001\na\t1!\0333!\021\035\021\003\0011A\005\002]\tAA\\1nK\"9A\005\001a\001\n\003)\023\001\0038b[\026|F%Z9\025\005\031J\003CA\006(\023\tACB\001\003V]&$\bb\002\026$\003\003\005\r\001G\001\004q\022\n\004B\002\027\001A\003&\001$A\003oC6,\007\005C\004/\001\001\007I\021B\030\002\r\035,g\016Z3s+\005\001\004CA\0062\023\t\021DBA\002J]RDq\001\016\001A\002\023%Q'\001\006hK:$WM]0%KF$\"A\n\034\t\017)\032\024\021!a\001a!1\001\b\001Q!\nA\nqaZ3oI\026\024\b\005\003\004;\001\001\006K\001M\001\004C\036,\007") public class Persons { public String id() { return this.id; } private final String id = "1234"; public String name() { return this.name; } public void name_$eq(String x$1) { this.name = x$1; } private String name = ""; private int gender() { return this.gender; } private void gender_$eq(int x$1) { this.gender = x$1; } private int gender = 0; private int age = 0; }
2.构造方法的定义
1)无参主构造函数的定义
package com.jason.qianfeng class Constructor { var name = "jj" println("jason") }
反编译结果:
package com.jason.qianfeng; import scala.Predef.; import scala.reflect.ScalaSignature; @ScalaSignature(bytes="\006\001}2A!\001\002\001\023\tY1i\0348tiJ,8\r^8s\025\t\031A!\001\005rS\006tg-\0328h\025\t)a!A\003kCN|gNC\001\b\003\r\031w.\\\002\001'\t\001!\002\005\002\f\0355\tABC\001\016\003\025\0318-\0317b\023\tyAB\001\004B]f\024VM\032\005\006#\001!\tAE\001\007y%t\027\016\036 \025\003M\001\"\001\006\001\016\003\tAqA\006\001A\002\023\005q#\001\003oC6,W#\001\r\021\005eqR\"\001\016\013\005ma\022\001\0027b]\036T\021!H\001\005U\0064\030-\003\002 5\t11\013\036:j]\036Dq!\t\001A\002\023\005!%\001\005oC6,w\fJ3r)\t\031c\005\005\002\fI%\021Q\005\004\002\005+:LG\017C\004(A\005\005\t\031\001\r\002\007a$\023\007\003\004*\001\001\006K\001G\001\006]\006lW\rI\004\006W\tA\t\001L\001\f\007>t7\017\036:vGR|'\017\005\002\025[\031)\021A\001E\001]M\021QF\003\005\006#5\"\t\001\r\013\002Y!)!'\fC\001g\005!Q.Y5o)\t\031C\007C\0036c\001\007a'\001\003be\036\034\bcA\0068s%\021\001\b\004\002\006\003J\024\030-\037\t\003uur!aC\036\n\005qb\021A\002)sK\022,g-\003\002 })\021A\b\004") public class Constructor { public String name() { return this.name; } public void name_$eq(String x$1) { this.name = x$1; } private String name = "jj"; public Constructor() { Predef..MODULE$.println("jason"); } public static void main(String[] paramArrayOfString) { Constructor..MODULE$.main(paramArrayOfString); } }
反编译后可以看到,系统会自动生成一个无参的构造方法,并且调用了类中定义的println 语句(可以换成初始化的功能语句)
2)带参数的主构造函数和辅助构造函数
package com.jason.qianfeng class Constructor(aa:Int,val bb:Int) {//定义带参数的主构造函数 def this(aa:Int,bb:Int,name:String){//定义辅助构造函数 this(aa,bb) this.name = name } var name = "jj" println("jason") }
反编译后的结果:
package com.jason.qianfeng; import scala.Predef.; import scala.reflect.ScalaSignature; @ScalaSignature(bytes="\006\001A3A!\001\002\001\023\tY1i\0348tiJ,8\r^8s\025\t\031A!\001\005rS\006tg-\0328h\025\t)a!A\003kCN|gNC\001\b\003\r\031w.\\\002\001'\t\001!\002\005\002\f\0355\tABC\001\016\003\025\0318-\0317b\023\tyAB\001\004B]f\024VM\032\005\t#\001\021\t\021)A\005%\005\021\021-\031\t\003\027MI!\001\006\007\003\007%sG\017\003\005\027\001\t\025\r\021\"\001\030\003\t\021'-F\001\023\021!I\002A!A!\002\023\021\022a\0012cA!)1\004\001C\0019\0051A(\0338jiz\"2!H\020!!\tq\002!D\001\003\021\025\t\"\0041\001\023\021\0251\"\0041\001\023\021\025Y\002\001\"\001#)\021i2\005J\023\t\013E\t\003\031\001\n\t\013Y\t\003\031\001\n\t\013\031\n\003\031A\024\002\t9\fW.\032\t\003Q-r!aC\025\n\005)b\021A\002)sK\022,g-\003\002-[\t11\013\036:j]\036T!A\013\007\t\017\031\002\001\031!C\001_U\t\001\007\005\0022m5\t!G\003\0024i\005!A.\0318h\025\005)\024\001\0026bm\006L!\001\f\032\t\017a\002\001\031!C\001s\005Aa.Y7f?\022*\027\017\006\002;{A\0211bO\005\003y1\021A!\0268ji\"9ahNA\001\002\004\001\024a\001=%c!1\001\t\001Q!\nA\nQA\\1nK\002:QA\021\002\t\002\r\0131bQ8ogR\024Xo\031;peB\021a\004\022\004\006\003\tA\t!R\n\003\t*AQa\007#\005\002\035#\022a\021\005\006\023\022#\tAS\001\005[\006Lg\016\006\002;\027\")A\n\023a\001\033\006!\021M]4t!\rYajJ\005\003\0372\021Q!\021:sCf\004") public class Constructor { public int bb() { return this.bb; } public Constructor(int aa, int bb, String name) { this(aa, bb); name_$eq(name); } public String name() { return this.name; } public void name_$eq(String x$1) { this.name = x$1; } private String name = "jj"; public Constructor(int aa, int bb) { Predef..MODULE$.println("jason"); } public static void main(String[] paramArrayOfString) { Constructor..MODULE$.main(paramArrayOfString); } }
通过反编译后的结果可知:
a.若主构造函数中参数带有 val 或 var关键字则该参数会变成类的属性,否则只是一个普通的参数
b.辅助构造函数的定义中,必须首先都用其他构造函数(主/辅助)
3)私有主构造函数的创建
只需在主构造参数前加private 修饰符
class Constructor private(aa:Int,val bb:Int) { def this(aa:Int,bb:Int,name:String){ this(aa,bb) this.name = name } var name = "jj" println("jason") }
3.单例对象
package com.jason.qianfeng object Logger { def logger(msg: String): Unit = { println(msg) } } class Test { Logger.logger("创建Test对象成功") } object Exe{ def main(args: Array[String]): Unit = { new Test() } }
scala中不存在static 类和static属性,取而代之的object 单例对象,单例对象是不带参数的,因为无法实例化,可以把单例对象作为一个工具类来使用
4.伴生对象,伴生类
package com.jason.qianfeng class Worker { private val id = Worker.getUniqId } object Worker { private var id = 0 private def getUniqId: Int = { id += 1 id } def getId(worker: Worker): Int = { worker.id } } object TestWorker extends App { //一种新的测试方法,与main主函数功能相同 val workers = for (i <- 1 to 10) yield new Worker() workers.foreach(wk => println(Worker.getId(wk))) }
在同一个文件中定义一个与类名相同的object 那么这个object 叫做这个类的半生对象,这个类叫做这个这个对象的伴生类,伴生对象和半生类可以互相访问彼此的私有属性。