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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

本節主要內容

1 類定義、創建對象
2 主構造器
3 輔助構造器

類定義、創建對象

//采用關鍵字class定義 class Person {//類成員必須初始化,否則會報錯//這里定義的是一個公有成員var name:String=null }

Person類在編譯后會生成Person.class文件

利用javap -prviate Person命令查看字節碼文件內容,可以看得到以下內容

D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進制文件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

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

//默認已經有構建函數,所以可以直接new scala> val p=new Person() p: Person = Person@84c504//直接調用getter和setter方法 //setter方法 scala> p.name_=("john") //getter方法 scala> p.name res2: String = john//直接修改,但其實調用的是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 警告: 二進制文件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(); }

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

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

從代碼執行產生的結果,我們可以知道:通過p.name=“john”這種方式進行賦值,調用者并不需要知道是其通過方法調用還是字段訪問來進行操作的,這便是著名的統一訪問原則

如果類的成員域是val類型的變量,則只會生成getter方法

class Person {//類成員必須初始化,否則會報錯//這里定義的是一個val公有成員val name:String="john" }D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進制文件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(); }

從字節碼文件中可以看出:val變量對應的是java中的final類型變量,只生成了getter方法

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

class Person {//類成員必須初始化,否則會報錯//private[this]修飾private[this] var name:String="john" }D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進制文件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語言當中,在定義JavaBean的時候生成的都是setXxx()、getXxx()方法,但scala語言生成的getter方法和setter方法并不是這樣的,如果也需要程序自動會生成getter方法和setter方法,則需要引入 scala.reflect.BeanProperty
然后采用注解的方式修飾變量

class Person {//類成員必須初始化,否則會報錯//@BeanProperty用于生成getXxx,setXxx方法@BeanProperty var name:String="john" }D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進制文件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方法產生的規則

來源:scala for the impatient

類主構造器

主構造器的定義與類的定義交織在一直,將構造器參數直接放在類名稱之后,如下代碼:

//下列代碼不但定義了一個類Person,還定義了主構造器,主構造器的參數為String、Int類型 class Person(val name:String,val age:Int)D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進制文件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語言編寫的代碼等同 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

主構造器會執行類定義中的所有語句,例如

//當在創建對象時,需要進行相關初始化操作時,可以將初始化語句放在類體中,同樣也可以在類中添加或重寫相關方法 class Person(val name:String,val age:Int){//println將作為主構建器中的一部分,在創建對象時被執行println("constructing Person ........")//重寫toString()方法override def toString()= name + ":"+ age }scala> val p=new Person("john",29) constructing Person ........ p: Person = john:29
  • 12

回過頭來看的話,前面我們定義的Person類是一種無參主構建器

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

主構建器還可以使用默認參數

//默認參數的主構建器 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

主構造器中的參數還可以加訪問控制符

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

當主構造器的參數不用var或val修飾的時候,參數會生成類的私有val成員,并且不會產生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 警告: 二進制文件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); }//與下面類定義等同 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 警告: 二進制文件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類中的toString()方法去掉,則類中無任何地方使用了主構造器的參數,此時主構造器參數不會生成類成員

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

下面圖給出了Scala中主構建器參數生成類成員和方法時的規則

來源:scala for the impatient

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

//類名后面緊跟private關鍵字可以將主構建器設為私有,不允許外部使用 class Person private(var name:String,var age:Int){println("constructing Person ........") }//生成的字節碼文件如下,可以看到其構建函數已經為private了 D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進制文件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); }//此時不能直接這么用 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)^

輔助構造函數

前面講了,如果禁用掉了主構建器,則必須使用輔助構造函數來創建對象。輔助構造函數具有兩個特點:(1)輔助構建器的名稱為this,java中的輔助構造函數與類名相同,這常常會導致修改類名時出現不少問題,scala語言避免了這樣的問題;(2)調用輔助構造函數時,必須先調用主構造函數或其它已經定義好的構造函數。

3.1 我們首先看一下只有輔助構造函數的Person類

//只有輔助構造函數的類 class Person{//類成員private var name:String=nullprivate var age:Int=18private var sex:Int=0//輔助構造器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} }//字節碼文件 D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進制文件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); }//在定義輔助構造函數時,需要注意構造函數的順序 class Person{//類成員private var name:String=nullprivate var age:Int=18private var sex:Int=0//輔助構造器def this(name:String,age:Int,sex:Int){this(name,age)//此處會發生編譯錯誤,這是因為def this(name:String,age:Int)沒有被定義this.sex=sex}def this(name:String){this()this.name=name}def this(name:String,age:Int){this(name)this.age=age}}

3.2 帶主構造函數、輔助構造函數的Person類

//具有主構建函數和輔助構建函數的Person類 class Person(var name:String,var age:Int){//類成員private var sex:Int=0//輔助構造器def this(name:String,age:Int,sex:Int){this(name,age)this.sex=sex} }生成的字節碼文件如下: D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進制文件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

在主構造函數小節當中我們提到,有時候可能會禁用掉主構造函數,此時只能通過輔助構造函數來創建對象

//禁用主構造函數 class Person private(var name:String,var age:Int){//類成員private var sex:Int=0//輔助構造器def this(name:String,age:Int,sex:Int){this(name,age)this.sex=sex}}//其字節碼文件內容如下 D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtwy>javap -private Person 警告: 二進制文件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); }

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。