scala类成员导致错误“类'类'必须声明为抽象或实现成员'成员'”

我正在尝试学习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

}

我收到一个错误:


只有类可以有已声明但未定义的成员


繁星coding
浏览 90回答 4
4回答

婷婷同学_

这样做是可能的,但这是代码异味。假设有人创建了您的钱包实例。他们必须generateKeys在您的课程真正可用之前打电话。如果他们忘记并尝试使用密钥,他们将收到运行时错误或无意义的行为。相反,将它们设置在主构造函数(如Josh 建议的那样)或工厂/应用方法(如Andy 建议的那样)中。如果你还是想做如果你真的想要一个已声明但未初始化的字段......你不能,确切地说,甚至在 Java 中也不能。在 Java 中,未初始化的字段被隐式初始化为默认值(null对于对象)。在 Scala 中,您可以通过为其分配下划线 ( _) 来获得此行为:var publicKey: PublicKey = _var privateKey: PrivateKey = _这些将被初始化为空。不过,请不要这样做。您的代码的其他问题在 Scala 中,您应该更val喜欢var.您的所有变量都是公开的。我猜你至少打算balance保密,因为你也有一个getBalance方法。您的Person示例不遵循惯用风格,因为您可以将其写为class Person(var personName: String).

小唯快跑啊

摆脱def this() { ... }. 在 scala 中,构造函数体只是类声明之后的代码行。像这样:class Person(name: String) {    private val id: String = name    // ... other fields, methods, etc.}

互换的青春

如果您需要在创建对象时未初始化的值,最好将它们设为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因为类型系统和运行时会在您使用它时检查该值是否有效。但其他答案是正确的,如果可能的话,最好推迟创建这个对象,直到密钥可用。

收到一只叮咚

您可以在伴随对象上添加应用: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)  }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java