java - 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();
这还将在构造函数中创建一个PrivateKey
and并将其分配给相应的类成员。PublicKey
Wallet
我知道Scala使用了一种略有不同的方法,其中类只是可实例化对象的模板,而Object
s 是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 帖子中的建议添加一个伴随对象并遵循他们的建议:
object Wallet {
var privateKey: PrivateKey
var publicKey: PublicKey
}
我收到一个错误:
只有类可以有已声明但未定义的成员
TL;博士
我想将Wallet
Java代码转换为Scala代码,我该如何实现呢?
更新(澄清我原来的问题)
所以,答案并不反映我的实际问题(我的想法)。我将尝试澄清。
Scala 支持各种构造函数。
正如@Josh在这里提到的,你会发现主要的构造函数
class Person(name: String) {
var personName: String = name
}
辅助构造函数将是(通过扩展@Josh 的示例),例如:
def this() {
this("Unknown Person Name")
// additional code
}
这些构造函数在此处进行了详细讨论,值得一读。
我感兴趣的是这个。
由于我已经声明了一个成员privateKey
and publicKey
,所以我希望在我的班级中声明更多成员。并非所有这些成员都会在类初始化时实例化,但会在应用程序执行期间稍后实例化。
下面将为我上面描述的内容提供更多背景信息。我将实例化Wallet
, 并在稍后阶段调用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 代码中定义。
解决方案
这样做是可能的,但这是代码异味。假设有人创建了您的钱包实例。他们必须generateKeys
在您的课程真正可用之前打电话。如果他们忘记并尝试使用密钥,他们将收到运行时错误或无意义的行为。相反,将它们设置在主构造函数(如Josh 建议的那样)或工厂/应用方法(如Andy 建议的那样)中。
如果你还是想做
如果你真的想要一个已声明但未初始化的字段......你不能,确切地说,甚至在 Java 中也不能。在 Java 中,未初始化的字段被隐式初始化为默认值(null
对于对象)。在 Scala 中,您可以通过为其分配下划线 ( _
) 来获得此行为:
var publicKey: PublicKey = _
var privateKey: PrivateKey = _
这些将被初始化为空。不过,请不要这样做。
您的代码的其他问题
- 在 Scala 中,您应该更
val
喜欢var
. - 您的所有变量都是公开的。我猜你至少打算
balance
保密,因为你也有一个getBalance
方法。 - 您的
Person
示例不遵循惯用风格,因为您可以将其写为class Person(var personName: String)
.
推荐阅读
- asp.net - 使用 Page.LoadTemplate 并传递参数
- r - 循环写入新工作表
- java - 当@Version 是 Integer 类型时休眠重复记录,但在使用原始类型 int 时不休眠
- c# - 如何通过模式写入将 CSV 数据读入数据表
- javascript - Typescript 中动态 React 组件的条件类型
- python - 如果某个列的 var 较低,那么你想删除该列
- python - Tensorflow dnnregressor 不断给我相同的预测值
- c++ - 函数之前的预期初始化程序(容易修复?)
- python - Windows exe 文件的文件版本为十六进制数字
- r - RStudio:按因子水平组织组的平均值和中位数