日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Scala入门到精通——第六节:类和对象(一)

發(fā)布時(shí)間:2024/1/23 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Scala入门到精通——第六节:类和对象(一) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本節(jié)主要內(nèi)容

1 類(lèi)定義、創(chuàng)建對(duì)象
2 主構(gòu)造器
3 輔助構(gòu)造器

類(lèi)定義、創(chuàng)建對(duì)象

//采用關(guān)鍵字class定義 class Person {//類(lèi)成員必須初始化,否則會(huì)報(bào)錯(cuò)//這里定義的是一個(gè)公有成員var name:String=null }

Person類(lèi)在編譯后會(huì)生成Person.class文件

利用javap -prviate Person命令查看字節(jié)碼文件內(nèi)容,可以看得到以下內(nèi)容

D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private java.lang.String name;public java.lang.String name();public void name_$eq(java.lang.String);public cn.scala.xtwy.Person(); }
  • 1

從字節(jié)碼文件內(nèi)容可以看到:雖然我們只在Person類(lèi)中定義了一個(gè)類(lèi)成員(域)name,類(lèi)型為String,但Scala會(huì)默認(rèn)幫我們生成name()與name_=()及構(gòu)造函數(shù)Person()。其中name()對(duì)應(yīng)Java中的getter方法,name_=()對(duì)應(yīng)java中的setter方法(由于JVM中不允許出現(xiàn)=,所以用$eq代替。值得注意的是定義的是公有成員,但生成的字節(jié)碼中卻是以私有的方式實(shí)現(xiàn)的,生成的getter、setter方法是公有的
因此,可以直接new操作創(chuàng)建Person對(duì)象

//默認(rèn)已經(jīng)有構(gòu)建函數(shù),所以可以直接new scala> val p=new Person() p: Person = Person@84c504//直接調(diào)用getter和setter方法 //setter方法 scala> p.name_=("john") //getter方法 scala> p.name res2: String = john//直接修改,但其實(shí)調(diào)用的是p.name_=("jonh") scala> p.name="jonh" p.name: String = jonh//getter方法 scala> p.name res28: String = jonh

你也可以定義自己的getter和setter方法

class Person{//定義私有成員private var privateName:String=null;//getter方法def name=privateName//setter方法def name_=(name:String){this.privateName=name}}
  • 1
D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private java.lang.String privateName;private java.lang.String privateName();private void privateName_$eq(java.lang.String);public java.lang.String name();public void name_$eq(java.lang.String);public cn.scala.xtwy.Person(); }

從生成的字節(jié)碼中可以看出:(1)定義成私有成員,其getter、setter方法也是私有的;(2)直接能訪問(wèn)的是我們自己定義的getter、setter方法。下面給出的是調(diào)用方式

scala> val p=new Person() p: Person = Person@12d0b54scala> p.name res29: String = null//直接賦值法 scala> p.name="john" p.name: String = johnscala> p.name res30: String = john

從代碼執(zhí)行產(chǎn)生的結(jié)果,我們可以知道:通過(guò)p.name=“john”這種方式進(jìn)行賦值,調(diào)用者并不需要知道是其通過(guò)方法調(diào)用還是字段訪問(wèn)來(lái)進(jìn)行操作的,這便是著名的統(tǒng)一訪問(wèn)原則

如果類(lèi)的成員域是val類(lèi)型的變量,則只會(huì)生成getter方法

class Person {//類(lèi)成員必須初始化,否則會(huì)報(bào)錯(cuò)//這里定義的是一個(gè)val公有成員val name:String="john" }D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private final java.lang.String name;public java.lang.String name();public cn.scala.xtwy.Person(); }

從字節(jié)碼文件中可以看出:val變量對(duì)應(yīng)的是java中的final類(lèi)型變量,只生成了getter方法

如果將成員域定義為private[this],則不會(huì)生成getter、setter方法

class Person {//類(lèi)成員必須初始化,否則會(huì)報(bào)錯(cuò)//private[this]修飾private[this] var name:String="john" }D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private java.lang.String name;public cn.scala.xtwy.Person(); }
  • 1

在java語(yǔ)言當(dāng)中,在定義JavaBean的時(shí)候生成的都是setXxx()、getXxx()方法,但scala語(yǔ)言生成的getter方法和setter方法并不是這樣的,如果也需要程序自動(dòng)會(huì)生成getter方法和setter方法,則需要引入 scala.reflect.BeanProperty
然后采用注解的方式修飾變量

class Person {//類(lèi)成員必須初始化,否則會(huì)報(bào)錯(cuò)//@BeanProperty用于生成getXxx,setXxx方法@BeanProperty var name:String="john" }D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private java.lang.String name;public java.lang.String name();public void name_$eq(java.lang.String);public void setName(java.lang.String);public java.lang.String getName();public cn.scala.xtwy.Person(); }

下圖給出的是getter、setter方法產(chǎn)生的規(guī)則

來(lái)源:scala for the impatient

類(lèi)主構(gòu)造器

主構(gòu)造器的定義與類(lèi)的定義交織在一直,將構(gòu)造器參數(shù)直接放在類(lèi)名稱(chēng)之后,如下代碼:

//下列代碼不但定義了一個(gè)類(lèi)Person,還定義了主構(gòu)造器,主構(gòu)造器的參數(shù)為String、Int類(lèi)型 class Person(val name:String,val age:Int)D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private final java.lang.String name;private final int age;public java.lang.String name();public int age();public cn.scala.xtwy.Person(java.lang.String, int); }//不難看出:上面的代碼與下列java語(yǔ)言編寫(xiě)的代碼等同 public class Person{private final String name;private final int age;public Person(String name,int age){this.name=name;this.age=age;}public String getName(){ return name}public int getAge() {return age} }//具體使用操作如下: scala> val p=new Person("john",29) p: Person = Person@abdc0fscala> p.name res31: String = johnscala> p.age res32: Int = 29

主構(gòu)造器會(huì)執(zhí)行類(lèi)定義中的所有語(yǔ)句,例如

//當(dāng)在創(chuàng)建對(duì)象時(shí),需要進(jìn)行相關(guān)初始化操作時(shí),可以將初始化語(yǔ)句放在類(lèi)體中,同樣也可以在類(lèi)中添加或重寫(xiě)相關(guān)方法 class Person(val name:String,val age:Int){//println將作為主構(gòu)建器中的一部分,在創(chuàng)建對(duì)象時(shí)被執(zhí)行println("constructing Person ........")//重寫(xiě)toString()方法override def toString()= name + ":"+ age }scala> val p=new Person("john",29) constructing Person ........ p: Person = john:29
  • 12

回過(guò)頭來(lái)看的話,前面我們定義的Person類(lèi)是一種無(wú)參主構(gòu)建器

//Person類(lèi)具有無(wú)參主構(gòu)建器 class Person {println("constructing Person....")val name:String="john" }scala> val p=new Person() constructing Person.... p: Person = Person@79895f

主構(gòu)建器還可以使用默認(rèn)參數(shù)

//默認(rèn)參數(shù)的主構(gòu)建器 class Person(val name:String="",val age:Int=18){println("constructing Person ........")override def toString()= name + ":"+ age }scala> val p=new Person constructing Person ........ p: Person = :18scala> val p=new Person("john") constructing Person ........ p: Person = john:18

主構(gòu)造器中的參數(shù)還可以加訪問(wèn)控制符

//默認(rèn)參數(shù)的主構(gòu)建器,參數(shù)帶訪問(wèn)控制符號(hào) //age變成私有成員,其getter方法是私有的,外部不能訪問(wèn) class Person(val name:String="",private val age:Int=18){println("constructing Person ........")override def toString()= name + ":"+ age }

當(dāng)主構(gòu)造器的參數(shù)不用var或val修飾的時(shí)候,參數(shù)會(huì)生成類(lèi)的私有val成員,并且不會(huì)產(chǎn)生getter和setter方法

//不加變量修飾符 class Person(name:String,age:Int){println("constructing Person ........")override def toString()= name + ":"+ age }D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private final java.lang.String name;private final int age;public java.lang.String toString();public cn.scala.xtwy.Person(java.lang.String, int); }//與下面類(lèi)定義等同 class Person(private[this] val name:String,private[this] val age:Int){println("constructing Person ........")override def toString()= name + ":"+ age }D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private final java.lang.String name;private final int age;public java.lang.String toString();public cn.scala.xtwy.Person(java.lang.String, int); }

值得注意的是,將上述Person類(lèi)中的toString()方法去掉,則類(lèi)中無(wú)任何地方使用了主構(gòu)造器的參數(shù),此時(shí)主構(gòu)造器參數(shù)不會(huì)生成類(lèi)成員

即將 //不加變量修飾符 class Person(name:String,age:Int){println("constructing Person ........")override def toString()= name + ":"+ age } 改成: class Person( val name:String,age:Int){println("constructing Person ........") }其字節(jié)碼文件如下: D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {public cn.scala.xtwy.Person(java.lang.String, int); } //可以看出,主構(gòu)造器參數(shù)不會(huì)生成類(lèi)成員
  • 1

下面圖給出了Scala中主構(gòu)建器參數(shù)生成類(lèi)成員和方法時(shí)的規(guī)則

來(lái)源:scala for the impatient

在某些情況下,可能需要禁用主構(gòu)建器,代碼如下:

//類(lèi)名后面緊跟private關(guān)鍵字可以將主構(gòu)建器設(shè)為私有,不允許外部使用 class Person private(var name:String,var age:Int){println("constructing Person ........") }//生成的字節(jié)碼文件如下,可以看到其構(gòu)建函數(shù)已經(jīng)為private了 D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private java.lang.String name;private int age;public java.lang.String name();public void name_$eq(java.lang.String);public int age();public void age_$eq(int);private cn.scala.xtwy.Person(java.lang.String, int); }//此時(shí)不能直接這么用 scala> val p=new Person("john",19) <console>:9: error: constructor Person in class Person cannot be accessed in obj ect $iwval p=new Person("john",19)^

輔助構(gòu)造函數(shù)

前面講了,如果禁用掉了主構(gòu)建器,則必須使用輔助構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象。輔助構(gòu)造函數(shù)具有兩個(gè)特點(diǎn):(1)輔助構(gòu)建器的名稱(chēng)為this,java中的輔助構(gòu)造函數(shù)與類(lèi)名相同,這常常會(huì)導(dǎo)致修改類(lèi)名時(shí)出現(xiàn)不少問(wèn)題,scala語(yǔ)言避免了這樣的問(wèn)題;(2)調(diào)用輔助構(gòu)造函數(shù)時(shí),必須先調(diào)用主構(gòu)造函數(shù)或其它已經(jīng)定義好的構(gòu)造函數(shù)。

3.1 我們首先看一下只有輔助構(gòu)造函數(shù)的Person類(lèi)

//只有輔助構(gòu)造函數(shù)的類(lèi) class Person{//類(lèi)成員private var name:String=nullprivate var age:Int=18private var sex:Int=0//輔助構(gòu)造器def this(name:String){this()this.name=name}def this(name:String,age:Int){this(name)this.age=age}def this(name:String,age:Int,sex:Int){this(name,age)this.sex=sex} }//字節(jié)碼文件 D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private java.lang.String name;private int age;private int sex;private java.lang.String name();private void name_$eq(java.lang.String);private int age();private void age_$eq(int);private int sex();private void sex_$eq(int);public cn.scala.xtwy.Person();public cn.scala.xtwy.Person(java.lang.String);public cn.scala.xtwy.Person(java.lang.String, int);public cn.scala.xtwy.Person(java.lang.String, int, int); }//在定義輔助構(gòu)造函數(shù)時(shí),需要注意構(gòu)造函數(shù)的順序 class Person{//類(lèi)成員private var name:String=nullprivate var age:Int=18private var sex:Int=0//輔助構(gòu)造器def this(name:String,age:Int,sex:Int){this(name,age)//此處會(huì)發(fā)生編譯錯(cuò)誤,這是因?yàn)閐ef this(name:String,age:Int)沒(méi)有被定義this.sex=sex}def this(name:String){this()this.name=name}def this(name:String,age:Int){this(name)this.age=age}}

3.2 帶主構(gòu)造函數(shù)、輔助構(gòu)造函數(shù)的Person類(lèi)

//具有主構(gòu)建函數(shù)和輔助構(gòu)建函數(shù)的Person類(lèi) class Person(var name:String,var age:Int){//類(lèi)成員private var sex:Int=0//輔助構(gòu)造器def this(name:String,age:Int,sex:Int){this(name,age)this.sex=sex} }生成的字節(jié)碼文件如下: D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private java.lang.String name;private int age;private int sex;public java.lang.String name();public void name_$eq(java.lang.String);public int age();public void age_$eq(int);private int sex();private void sex_$eq(int);public cn.scala.xtwy.Person(java.lang.String, int);public cn.scala.xtwy.Person(java.lang.String, int, int); }
  • 1

在主構(gòu)造函數(shù)小節(jié)當(dāng)中我們提到,有時(shí)候可能會(huì)禁用掉主構(gòu)造函數(shù),此時(shí)只能通過(guò)輔助構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象

//禁用主構(gòu)造函數(shù) class Person private(var name:String,var age:Int){//類(lèi)成員private var sex:Int=0//輔助構(gòu)造器def this(name:String,age:Int,sex:Int){this(name,age)this.sex=sex}}//其字節(jié)碼文件內(nèi)容如下 D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進(jìn)制文件Person包含cn.scala.xtwy.Person Compiled from "Person.scala" public class cn.scala.xtwy.Person {private java.lang.String name;private int age;private int sex;public java.lang.String name();public void name_$eq(java.lang.String);public int age();public void age_$eq(int);private int sex();private void sex_$eq(int);private cn.scala.xtwy.Person(java.lang.String, int);public cn.scala.xtwy.Person(java.lang.String, int, int); }

總結(jié)

以上是生活随笔為你收集整理的Scala入门到精通——第六节:类和对象(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。