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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

[转载] Scala继承与Java的区别

發布時間:2025/3/11 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转载] Scala继承与Java的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考鏈接: Java中將final與繼承一起使用

在之前的筆記Java靜態屬性和方法的繼承問題中,通過具體的實驗證明,在子類中重寫父類的字段時并沒有覆蓋父類的字段,只是隱藏了父類的字段。而在scala中則不同,scala子類的同名字段會重寫且覆蓋父類的同名字段,這里做了個簡單實驗,并記錄下來。?

Parent.scala?

class Parent {

? val normalStr: String = "Normal member of parent."

?

? def normalMethod() = {

? ? println("Normal method of parent.")

? }

}?

定義了一個字段normalStr和一個方法normalMethod(),在Scala中,類的字段是由一個私有屬性和對應的getter/setter方法組成的。?

Child.scala?

class Child extends Parent {

? override val normalStr: String = "Normal member of child."

?

? override def normalMethod() = {

? ? println("Normal method of child.")

? }

}?

子類Child繼承了父類Parent,并override父類的normalStr和normalMethod()。?

TestMain和Result?

object TestMain{

? def main(args: Array[String]) {

? ? val child: Child = new Child

? ? println(child.normalStr)

? ? child.normalMethod()

?

? ? //val child1:Parent = child.asInstanceOf[Parent]

? ? //采用Parent類型的變量指向創建的Child對象

? ? val child1:Parent = new Child

? ? println(child1.normalStr)

? ? child1.normalMethod()

? }

}?

輸出的結果如下:?

Normal member of child.

Normal method of child.

Normal member of child.

Normal method of child.?

從結果可以看出,子類重寫并覆蓋了父類的同名屬性和方法?

Scala子類的構造順序?

這里順便記錄下Scala子類的構造順序,這里直接用書上給出的例子,以便后續查看:?

先寫兩個類,一個父類Creature.scala,一個子類Ant.scala:?

Creature?

class Creature {

? ? val range: Int = 10

? ? val env: Array[Int] = new Array[Int](range)

? ? def show(): Unit = {

? ? ? ?println(range)

? ? }

}?

Ant?

class Ant extends Creature {

? ? override val range = 2

}?

現在創建一個Ant的對象ant,那么ant.env.length的值是多少,憑第一感覺應該是10或者2,然而答案是0,接下來我寫下ant創建的過程中構造器的運行順序:?

首先調用父類Creature的構造器(父類的構造器先于子類的構造器被調用),所以首先把range設置為10。為了后續的說明這里說明下,類的字段是由一個私有屬性和對應的getter和setter方法組成的,而子類在重寫父類的同名字段時,對于val類型的屬性子類重寫了getter方法。接下來初始化env數組,所以需要調用range的getter方法,然而子類已經重寫了getter方法,且子類并沒初始化,所有的字段都是對象創建過程中,內存清零后的默認值,所以此時range的值為0。這也就解釋了上述問題的疑問。接下來調用子類的構造器,range被設為2。?

所以在構造器中,對象的初始化不應該依賴于val的值,因為val的值對應的getter方法可能會被子類重寫覆蓋。解決辦法有:?

將val聲明為final。(簡單高效,但是不夠靈活)在超類中將val聲明為lazy。(簡單靈活,但是不夠高效)還有種就是子類中使用提前定義語法。(這個就不介紹了)?

ant對象調用show()方法輸出的則是子類range的值,即為2。而在Java中,則是父類的range的值:10。主要原因還是由于在Scala中,子類重寫父類的屬性或者方法,覆蓋了父類的屬性和方法,而在Java中,只有非靜態的方法會被子類重寫覆蓋,而非靜態/靜態屬性和靜態方法都只是被隱藏了。?

主要參考:《快學Scala》

總結

以上是生活随笔為你收集整理的[转载] Scala继承与Java的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

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