scala 类,伴生对象

Posted jason-dong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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="0601m2A!01020123	901+32:t_:34(BA020503!	30.318gK:<‘BA03070325Q27m]8o2505921aA2p[16011C010113!	Ya"D01
2505i21!B:dC2f27BA
0531	e.37*fM")210301C01%051A(338jiz"22a05	03)01i21A0105-0121
21"013003	IG-F0131!	IBD0402f5%21104D0107!J,G-324
05uq"AB*ue&twM03023431!1010501Q01
a	1!333!21352103011A0502]	AA\1nK"9A0501a01
03)2301038b[26|F%Z9250531J03CA06(23	ACB0103V]&$b0226$030305
01G0104q22
04B022701A03&01$A03oC6,0705C04/010107I21B3002
35,g16Z3s+050104CA06223	21DBA02J]RDq011601A0223%Q‘0106hK:$WM]0%KF$"A
34	17)322421!a01a!10101Q!
A
qaZ3oI2624050304;010106K01M0104C36,07")
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="0601}2A!01020123	Y1i348tiJ,8
^8s25	31A!0105rS06tg-328h25	)a!A03kCN|gNC0103
31w.\0201‘	01!020502f355	ABC01160325318-317b23	yAB0104B]f24VM320506#01!	AE0107y%t271636 2503M01"0106011603	AqA0601A022305q#0103oC6,W#01
2105eqR"01161305ma2201027b]36T21!H0105U06430-0302 5	111336:j]36Dq!	01A022305!%0105oC6,wfJ3r)	31c050502fI%21Q05040205+:LG17C04(A0505	3101
0207a$23070304*010106K01G0106]06lW
I0406W	A	01L01f07>t71736:vGR|‘17050225[31)21A01E01]M21QF030506#5"	01
1302Y!)!‘fC01g05!Q.Y5o)	31C07C036c0107a‘0103be3634cA068s%210104020603J2430-37	03uur!aC36
05qb21A02)sK22,g-0302 })21A04")
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="0601A3A!01020123	Y1i348tiJ,8
^8s25	31A!0105rS06tg-328h25	)a!A03kCN|gNC0103
31w.\0201‘	01!020502f355	ABC01160325318-317b23	yAB0104B]f24VM3205	#0121	21)A05%052121-31	0327MI!0106070307%sG1703052701	25
21"013003	21‘-F012321!I02A!A!02232122a012cA!)10401C019051A(338jiz"2!H20!!	q02!D01032125	"041012321251"04101232125Y0201"01#)21i205J23	13E	033101
	13Y	033101
	1331
0331A2402	9fW.32	03Q-r!aC25
05)b21A02)sK22,g-0302-[	111336:j]36T!A1307	1731020131!C01_U	010705022m5	!G03024i05!A.318h2505)2401026bm06L!01f32	17a020131!C01s05Aa.Y7f?22*27170602;{A211bO0503y121A!268ji"9ahNA0102040124a01=%c!101	01Q!
A
QA\1nK02:QA2102	02
131bQ8ogR24Xo31;peB21a0422040603	A	!R
03	*AQa07#050235#22a2105062322#	AS0105[06Lg160602;27")A
23a013306!21M]4t!
YajJ050337221Q!21:sCf04")
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 叫做这个类的半生对象,这个类叫做这个这个对象的伴生类,伴生对象和半生类可以互相访问彼此的私有属性。

 

以上是关于scala 类,伴生对象的主要内容,如果未能解决你的问题,请参考以下文章

scala 单例伴生对象伴生类

Scala编程之伴生对象

Scala伴生对象

scala 类,伴生对象

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

Scala 一张图带你看懂什么是伴生对象