亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

scala類成員導致錯誤“類'類'必須聲明為抽象或實現成員'成員'”

scala類成員導致錯誤“類'類'必須聲明為抽象或實現成員'成員'”

繁星coding 2022-07-06 10:00:55
我正在嘗試學習Scala Object和Class。我來自Java,它與 Scala 非常相似,但在語法上不一樣。在Java中,我會創建一個類似的類:public class Wallet {    private PublicKey publicKey;    private PrivateKey privateKey;    private int balance = 0;    public Wallet() throws NoSuchAlgorithmException {        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");        KeyPair keyPair = keyPairGenerator.generateKeyPair();        privateKey = keyPair.getPrivate();        publicKey = keyPair.getPublic();    }    public int getBalance(){        return balance;    }}這定義了一個Wallet對象的模板,我可以在Java中將其實例化為:Wallet wallet = new Wallet();這還將在構造函數中創建一個PrivateKeyand并將其分配給相應的類成員。PublicKeyWallet我知道Scala使用了一種略有不同的方法,其中類只是可實例化對象的模板,而Objects 是Singleton持久存儲信息的類型對象。另外,根據這篇文章,我發現 an在文件Object中經常用作伴隨對象。Class使用上面的Wallet示例,我試圖在Scala中重新創建它。這是我到目前為止所擁有的:class Wallet {  var publicKey: PublicKey  var privateKey: PrivateKey  var balance: Int = 0  def this() {    this    val keyPair =  KeyPairGenerator.getInstance("SHA-256").generateKeyPair()    privateKey = keyPair.getPrivate    publicKey = keyPair.getPublic  }  def getBalance(): Int = {    balance  }}問題:“錢包”類必須聲明為抽象或在“com.simple.blockchain.Wallet”中實現抽象成員“publicKey:PublicKey”現在這讓我很困惑。在Java中,將未實例化的對象聲明為類成員通常會是一個問題,因此,如果我嘗試按照之前的 SO 帖子中的建議添加一個Companion Object并遵循他們的建議:object Wallet {  var privateKey: PrivateKey  var publicKey: PublicKey}我收到一個錯誤:只有類可以有已聲明但未定義的成員
查看完整描述

4 回答

?
婷婷同學_

TA貢獻1844條經驗 獲得超8個贊

這樣做是可能的,但這是代碼異味。假設有人創建了您的錢包實例。他們必須generateKeys在您的課程真正可用之前打電話。如果他們忘記并嘗試使用密鑰,他們將收到運行時錯誤或無意義的行為。相反,將它們設置在主構造函數(如Josh 建議的那樣)或工廠/應用方法(如Andy 建議的那樣)中。


如果你還是想做

如果你真的想要一個已聲明但未初始化的字段......你不能,確切地說,甚至在 Java 中也不能。在 Java 中,未初始化的字段被隱式初始化為默認值(null對于對象)。在 Scala 中,您可以通過為其分配下劃線 ( _) 來獲得此行為:


var publicKey: PublicKey = _

var privateKey: PrivateKey = _

這些將被初始化為空。不過,請不要這樣做。

您的代碼的其他問題

  1. 在 Scala 中,您應該更val喜歡var.

  2. 您的所有變量都是公開的。我猜你至少打算balance保密,因為你也有一個getBalance方法。

  3. 您的Person示例不遵循慣用風格,因為您可以將其寫為class Person(var personName: String).


查看完整回答
反對 回復 2022-07-06
?
小唯快跑啊

TA貢獻1863條經驗 獲得超2個贊

擺脫def this() { ... }. 在 scala 中,構造函數體只是類聲明之后的代碼行。像這樣:


class Person(name: String) {

    private val id: String = name


    // ... other fields, methods, etc.

}


查看完整回答
反對 回復 2022-07-06
?
互換的青春

TA貢獻1797條經驗 獲得超6個贊

如果您需要在創建對象時未初始化的值,最好將它們設為Option值:


class Wallet {

  private var publicKey: Option[PublicKey] = None

  private var privateKey: Option[PrivateKey] = None

  private var balance: Int = 0


  def generateKeys(): Unit = {

    val keyPair =  KeyPairGenerator.getInstance("SHA-256").generateKeyPair()

    privateKey = Some(keyPair.getPrivate)

    publicKey = Some(keyPair.getPublic)

  }


  def getBalance = balance

}

這比使用更安全,null因為類型系統和運行時會在您使用它時檢查該值是否有效。


但其他答案是正確的,如果可能的話,最好推遲創建這個對象,直到密鑰可用。


查看完整回答
反對 回復 2022-07-06
?
收到一只叮咚

TA貢獻1821條經驗 獲得超5個贊

您可以在伴隨對象上添加應用:


class Wallet private (val privateKey: PrivateKey, publicKey: PublicKey, balance: Int) {

  def getBalance(): Int = balance

}

object Wallet {

  def apply(): Wallet = {

    val keyPair =  KeyPairGenerator.getInstance("SHA-256").generateKeyPair()

    val privateKey = keyPair.getPrivate

    val privateKey = keyPair.getPublic

    new Wallet(privateKey, privateKey, 0)

  }

}


查看完整回答
反對 回復 2022-07-06
  • 4 回答
  • 0 關注
  • 120 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號