Class Kotlin继承/子类
我是Kotlin的新手,来自JS(但无论如何,我是一个非常业余、自学成才的程序员)。在过去,我的方法只是完成它,但我一直喜欢Kotlin的简洁性,并希望避免在我的程序中的类似元素中进行不必要的复制。我想知道我是否可以得到一些关于父类的子类的指导。目前,我正在使用两种类型:Class Kotlin继承/子类,class,kotlin,inheritance,Class,Kotlin,Inheritance,我是Kotlin的新手,来自JS(但无论如何,我是一个非常业余、自学成才的程序员)。在过去,我的方法只是完成它,但我一直喜欢Kotlin的简洁性,并希望避免在我的程序中的类似元素中进行不必要的复制。我想知道我是否可以得到一些关于父类的子类的指导。目前,我正在使用两种类型: class Ratio(var num: Int, var den: Int) { var monzo: MutableList<Int> = calculateMonzo(num, den) v
class Ratio(var num: Int, var den: Int) {
var monzo: MutableList<Int> = calculateMonzo(num, den)
var sizeInCents: Double = calculateCents(num, den)
var centDeviation: Pair<Double, String> = calculateCentDeviation(num, den, monzo)
var notation: Triple<String, String, String> = calculateNotation(monzo)
var frequency: Double = calculateFrequency(num, den)
}
class比率(变量num:Int,变量den:Int){
var monzo:MutableList=calculateMonzo(num,den)
变量大小元素:Double=计算元素(num,den)
var centDeviation:Pair=calculateCentDeviation(num、den、monzo)
var表示法:三重=计算(monzo)
var频率:双=计算频率(num,den)
}
及
class Monzo(变量Monzo:List){
var num:Int=calculateRatio(monzo)。首先
变量:Int=calculateRatio(monzo)。秒
变量大小元素:Double=计算元素(num,den)
var centDeviation:Pair=calculateCentDeviation(num、den、monzo)
var hejiString:Triple=calculateNotation(monzo)
var频率:双=计算频率(num,den)
}
基本上,
Ratio()
或Monzo()
都代表相同的“事物”(分数或分数的素因子分解),并且仅依赖于用户的首选输入。最后,我计算“缺失”信息,然后从这一点开始,属性和计算是相同的。这些将在父类中(例如,Input()
)是有意义的,但我不确定如何最好地设置父类,然后在调用其中一个子类的实例时访问这些父属性。具有两个构造函数的单个类的示例:
class Ratio private constructor(
val num: Int,
val den: Int,
val monzo: List<Int>
) {
constructor(monzo: List<Int>): this(calculateRatio(monzo).first, calculateRatio(monzo).second, monzo)
constructor(num: Int, den: Int): this(num, den, calculateMonzo(num, den))
val sizeInCents: Double = calculateCents(num, den)
val centDeviation: Pair<Double, String> = calculateCentDeviation(num, den, monzo)
val notation: Triple<String, String, String> = calculateNotation(monzo)
val frequency: Double = calculateFrequency(num, den)
}
此外,所有属性都应该是
val
,而不是var
,因为它们依赖于比率的初始值。如果希望num
、den
和monzo
是可变的,那么应该为它们编写自定义设置程序,重新计算所有内容。在这种情况下,依赖于比率的属性可以是var
,但是使用私有setter。难道不能只有一个类和两个构造函数吗?如果您需要知道它是Ratio还是Monzo,那么最终添加一个枚举。这是否真的需要并行地存储、返回和操作这两种形式的数据(num/den和int list)? 对我来说,整洁的解决方案是对一个表单进行标准化,只有一个只存储该表单的类,然后提供一种从另一个表单创建表单的方法(通过二级构造函数或伴随对象中的工厂方法),并从中创建另一个表单(通过方法或带有自定义getter的属性)“@Pawel和gidds我当然可以想象一个单一的标准化。例如,素因子分解“monzo”(List)是更有用的形式,任何比率(num/den)都可以通过简单的函数轻松转换为monzo。你有没有办法给出一个使用二级构造函数的非常基本的例子?我觉得有些奇怪,但在细节上有些不确定……感谢-->所以根据使用Ratio()时的数据类型,将使用monzo构造函数还是num/den构造函数?我得到的错误是num、den和monzo必须初始化(在构造函数后面的代码中)。我需要某种init块或默认值吗?构造函数中的代码是否在其余代码之前执行?我认为将val num
、val den
和val monzo
移动到构造函数之前,然后假装这一点。
到每个构造函数中的每个引用可以解决问题,但它似乎没有…我试过玩,但保持相同的语法。当我复制您的示例时(从逻辑上讲,它应该可以满足我的需要),我在构造函数中没有错误,在val
定义本身中也没有错误val-num:Int
,val-den:Int
,和val-monzo:List
,但是在剩余的函数中每次num
,den
,或者调用monzo
,我得到的错误是必须初始化变量。我想我不需要引用主构造函数,因为没有主构造函数,所以有点不知所措……对不起,我错过了这里的执行顺序。属性初始化发生在构造函数阻塞之前,因此当任一构造函数尚未为前三个属性分配任何内容时,它无法计算所有依赖属性。因此,您毕竟需要一个主构造函数。查看更新的答案。太好了,工作非常完美,感谢您的帮助。我需要更多地了解val
与var
的区别——这种区别似乎比JS中const
和var
之间的区别更微妙
class Ratio private constructor(
val num: Int,
val den: Int,
val monzo: List<Int>
) {
constructor(monzo: List<Int>): this(calculateRatio(monzo).first, calculateRatio(monzo).second, monzo)
constructor(num: Int, den: Int): this(num, den, calculateMonzo(num, den))
val sizeInCents: Double = calculateCents(num, den)
val centDeviation: Pair<Double, String> = calculateCentDeviation(num, den, monzo)
val notation: Triple<String, String, String> = calculateNotation(monzo)
val frequency: Double = calculateFrequency(num, den)
}
companion object {
operator fun invoke(monzo: List<Int>) = with(calculateRatio(monzo)) { Ratio(first, second, monzo) }
}