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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Scala入门到精通——第十节 Scala类层次结构、Traits初步

發布時間:2024/1/23 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Scala入门到精通——第十节 Scala类层次结构、Traits初步 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本節主要內容

  • Scala類層次結構總覽
  • Scala中原生類型的實現方式解析
  • Nothing、Null類型解析
  • Traits簡介
  • Traits幾種不同使用方式
  • 1 Scala類層次結構

    Scala中的類層次結構圖如下:


    來源:Programming in scala

    從上面的類層次結構圖中可以看到,處于繼承層次最頂層的是Any類,它是scala繼承的根類,scala中所有的類都是它的子類
    Any類中定義了下面幾個方法:

    //==與!=被聲明為final,它們不能被子類重寫 final def ==(that: Any): Boolean final def !=(that: Any): Boolean def equals(that: Any): Boolean def hashCode: Int def toString: String

    從上面的代碼看可以看到,Any類中共包括了五個方法,其中==與!=被聲明為final類型的,因此它們不能被子類重寫,事實上==的真正實現是通過equals方法來實現的,而!=是通過!equals來實現的,因此如果想改變==與!=方法的行為的話,可以直接對equals進行重寫。

    根類Any有兩個子類,它們分別是AnyVal和AnyRef,其中AnyVal是所有scala內置的值類型( Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit.)的父類,其中 Byte, Short, Char, Int, Long, Float, Double, Boolean與Java中的byte,short,char,int,long,float,double,boolean原生類型對應,而Unit對應java中的void類型,由于( Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit)繼承AnyVal,而AnyVal又繼承Any,因此它們也可以調用toString等方法。

    scala> 2.0.hashCode res5: Int = 1073741824scala> 2.0 toString res6: String = 2.0

    值得一提的是,()可以作為Unit類型的實例,它同樣可以調用toString等方法

    scala> ().hashCode res7: Int = 0scala> ().toString res8: String = ()scala> ()==() <console>:8: warning: comparing values of types Unit and Unit using `==' will al ways yield true ()==() ^ res9: Boolean = true

    AnyRef是Any的另外一個子類,它是scala中所有非值類型的父類,對應Java.lang.Object類(可以看作是java.lang.Object類的別名),也即它是所有引用類型的父類(除值類型外)。那為什么不直接Java.lang.Object作為scala非值引用類型的父類呢?這是因為Scala還可以運行在其它平臺上如.Net,所以它使用了AnyRef這個類,在JVM上它對應的是java.lang.Object,而對于其它平臺有不同的實現。

    2 Scala中原生類型的實現方式解析

    scala采用與java相同原生類型存儲方式,由于性能方面及與java進行操作方面的考慮,scala對于原生類型的基本操作如加減乘除操作與java是一樣的,當需要遇到其他方法調用時,則使用java的原生類型封裝類來表示,如Int類型對應于java.lang.Integer類型,這種轉換對于我們使用者來說是透明的。

    在本課程的第二節中我們提到,scala中的==操作它不區分你是原生類型還是引用類型,例如

    scala> "abc"=="abc" res10: Boolean = true

    如果是在java語言中,它返回的是false。在scala中,對于原生類型,這種等于操作同java原生類型,而對于引用類型,它實際上是用equals方法對==方法進行實現,這樣避免了程序設計時存在的某些問題。那如果想判斷兩個引用類型是否相等時怎么辦呢? AnyRef中提供了eq、ne兩個方法用于判斷兩個引用是否相等,如

    scala> val x=new String("123") x: String = 123scala> val y=new String("123") y: String = 123scala> x==y res15: Boolean = truescala> x.eq(y) res16: Boolean = falsescala> x ne y res17: Boolean = true

    3 Nothing、Null類型解析

    在前面的類層次結構圖中可以看到,Null類型是所有AnyRef類型的子類型,也即它處于AnyRef類的底層,對應java中的null引用。而Nothing是scala類中所有類的子類,它處于scala類的最底層。
    這里面必須注意的是Null類型處于AnyRef類的底層,它不能夠作為值類型的子類,例如:

    scala> var x:Int=null <console>:7: error: type mismatch;found : Null(null)required: Int Note that implicit conversions are not applicable because they are ambiguous:both method Integer2intNullConflict in class LowPriorityImplicits of type (x: N ull)Intand method Integer2int in object Predef of type (x: Integer)Intare possible conversion functions from Null(null) to Intvar x:Int=null^

    Nothing這個類一般用于指示程序返回非正常結果,利用Nothing作為返回值可以增加程序的靈活性。例如:

    def error(msg:String):Nothing={throw new RuntimeException(msg)}def divide(x: Int, y: Int): Int = if (y != 0) x / y else error("can't divide by zero")
    • 1

    4 Traits簡介

    scala和java語言一樣,采用了很強的限制策略,避免了多種繼承的問題。在java語言中,只允許繼承一個超類,該類可以實現多個接口,但java接口有其自身的局限性:接口中只能包括抽象方法,不能包含字段、具體方法。Scala語言利用Trait解決了該問題,在scala的trait中,它不但可以包括抽象方法還可以包含字段和具體方法。trait的示例如下:

    //trait定義演示 trait DAO{//定義一個抽象方法,注意不需要加abstract//加了abstract反而會報錯def delete(id:String):Booleandef add(o:Any):Booleandef update(o:Any):Intdef query(id:String):List[Any] }
    • 1

    生成的字節碼文件反編譯后的結果:

    D:\ScalaWorkspace\ScalaChapter10\bin\cn\scala\xtwy>javap -private DAO.class Compiled from "Dao.scala" public interface cn.scala.xtwy.DAO {public abstract boolean delete(java.lang.String);public abstract boolean add(java.lang.Object);public abstract int update(java.lang.Object);public abstract scala.collection.immutable.List<java.lang.Object> query(java.l ang.String); }
    • 1

    下面的代碼演示了如果使用trait

    trait MysqlDAO{def add(o:Any):Booleandef update(o:Any):Intdef query(id:String):List[Any] }class DaoImpl extends MysqlDAO{def add(o:Any):Boolean=truedef update(o:Any):Int= 1def query(id:String):List[Any]=List(1,2,3) }
    • 1

    如果有多個trait的話:

    trait MysqlDAO{var recodeMount:Long=15000000000000Ldef add(o:Any):Booleandef update(o:Any):Intdef query(id:String):List[Any] }class DaoImpl extends MysqlDAO with Cloneable{def add(o:Any):Boolean=truedef update(o:Any):Int= 1def query(id:String):List[Any]=List(1,2,3) }

    5 Traits幾種不同使用方式

    1 當做java接口使用的trait,如

    //trait定義演示 trait DAO{//定義一個抽象方法,注意不需要加abstract//加了abstract反而會報錯def delete(id:String):Booleandef add(o:Any):Booleandef update(o:Any):Intdef query(id:String):List[Any] }

    2 帶具體實現的trait

    trait DAO{//delete方法有具體實現def delete(id:String):Boolean={println("delete implementation")true}def add(o:Any):Booleandef update(o:Any):Intdef query(id:String):List[Any] }

    這里定義的特質將生成兩個字節碼文件:

    D:\ScalaWorkspace\ScalaChapter10\bin\cn\scala\xtwy 的目錄2015/07/25 22:20 <DIR> . 2015/07/25 22:20 <DIR> .. 2015/07/25 22:20 575 DAO$class.class 2015/07/25 22:20 898 DAO.class2 個文件 1,473 字節2 個目錄 175,333,232,640 可用字節D:\ScalaWorkspace\ScalaChapter10\bin\cn\scala\xtwy>javap -private DAO$class.class Compiled from "Dao.scala" public abstract class cn.scala.xtwy.DAO$class {public static boolean delete(cn.scala.xtwy.DAO, java.lang.String);public static void $init$(cn.scala.xtwy.DAO); }D:\ScalaWorkspace\ScalaChapter10\bin\cn\scala\xtwy>javap -private DAO.class Compiled from "Dao.scala" public abstract class cn.scala.xtwy.DAO$class {public static boolean delete(cn.scala.xtwy.DAO, java.lang.String);public static void $init$(cn.scala.xtwy.DAO); }
    • 3

    從字節碼文件可以看出,帶有具體實現的trait是通過java中的抽象類來實現的。

    3 帶抽象字段的trait

    trait DAO{var recodeMount:Longdef delete(id:String):Boolean={println("delete implementation")true}def add(o:Any):Booleandef update(o:Any):Intdef query(id:String):List[Any] }

    4 具體字段的trait

    trait DAO{var recodeMount:Long=15000000000000Ldef delete(id:String):Boolean={println("delete implementation")true}def add(o:Any):Booleandef update(o:Any):Intdef query(id:String):List[Any] }

    總結

    以上是生活随笔為你收集整理的Scala入门到精通——第十节 Scala类层次结构、Traits初步的全部內容,希望文章能夠幫你解決所遇到的問題。

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