代码之家  ›  专栏  ›  技术社区  ›  CybeX

导致错误的scala类成员“class‘class’必须声明为abstract或实现成员‘member’”

  •  1
  • CybeX  · 技术社区  · 6 年前

    Object s和 Class . 我来自 爪哇

    爪哇 ,我将创建一个类,如:

    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 对象,我可以在

    Wallet wallet = new Wallet();
    

    这也将创建一个 PrivateKey PublicKey 构造函数并将其分配给相应的类成员。

    我明白 斯卡拉 使用稍有不同的方法,其中类只是可实例化对象的模板,并且 Object Singleton 键入持久存储信息的对象。

    而且,我发现 对象 Class 作为 伴生对象 this post .

    使用上面的 钱包 斯卡拉 . 这就是我目前所拥有的:

    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
      }
    }
    

    问题是:

    类“Wallet”必须声明为抽象或实现抽象 成员'publicKey:publicKey'in'com.simple.blockchain公司.钱包

    现在我很困惑。

    爪哇 ,将声明但未实例化的对象作为类成员通常是一个问题,因此如果我尝试添加 伴生对象

    object Wallet {
      var privateKey: PrivateKey
      var publicKey: PublicKey
    }
    

    我得到一个错误:

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

    TL;博士

    我想要一个 爪哇 斯卡拉 代码,我怎么能做到这一点?


    所以,答案并不能反映我的实际问题(我的想法)。我将试图澄清。

    @Josh提到的主构造函数 here

    class Person(name: String) {
        var personName: String = name
    }
    

    def this() {
        this("Unknown Person Name")
        // additional code
    }
    

    我们将讨论这些构造函数 here in some detail ,有助于阅读。

    我感兴趣的是这个。

    privateKey publicKey

    下面的内容将为我上面描述的内容提供更多的上下文。我将实例化 ,在稍后的阶段调用 wallet.generateKeys() .

    class Wallet {
    
      var publicKey: PublicKey
      var privateKey: PrivateKey
      var balance: Int = 0
    
      def generateKeys(): Unit = {
        val keyPair =  KeyPairGenerator.getInstance("SHA-256").generateKeyPair()
        privateKey = keyPair.getPrivate
        publicKey = keyPair.getPublic
      }
    
      def getBalance(): Int = {
        balance
      }
    }
    

    这将需要声明一个变量,但在运行时不实例化,直到需要它为止。

    在Scala代码中定义。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Tim    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

    但是其他的答案是正确的,如果可能的话,最好推迟创建这个对象,直到键可用为止。

        2
  •  3
  •   Josh    6 年前

    def this() { ... }

    class Person(name: String) {
        private val id: String = name
    
        // ... other fields, methods, etc.
    }
    
        3
  •  3
  •   Brian McCutchon    6 年前

    这是可能的,但是 it's a code smell . 假设有人拿你的钱包做了个例子。他们必须打电话 generateKeys 在你的课真的有用之前。如果他们忘记并试图使用密钥,他们将得到一个运行时错误或无意义的行为。相反,在主构造函数中设置这些 Josh suggests )或工厂/应用方法(如 Andy suggests ).

    但我喜欢反模式和代码的味道!

    null 对于对象)。在Scala中可以通过分配下划线来获得这种行为( _ )致:

    var publicKey: PublicKey = _
    var privateKey: PrivateKey = _
    

    这些将被初始化为空。不过,请不要这样做。

    代码的其他问题

    1. val var .
    2. 所有变量都是公共的。我猜你至少应该 balance 列兵,因为你也有 getBalance 方法。
    3. Person class Person(var personName) .
        4
  •  2
  •   Andy Hayden    6 年前

    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)
      }
    }