Kotlin类中constructor parameters与member variables的区别是什么?
核心误区纠正
首先你的认知存在两个关键错误:
- Kotlin 构造参数默认不是类的成员变量:只有加了
var/val修饰的构造参数才会自动成为类的成员,没有加修饰的只是构造方法的临时入参,仅在类初始化阶段(成员变量赋值、init代码块)可用,不会成为类的成员。 - 你所说的「
noOfSides在class Square内部无法修改」完全不成立:你在Square类中访问的noOfSides本质是继承自父类Polygon的public可变成员变量,你可以直接在Square内部对它赋值,修改的就是父类的这个成员值。
你的代码运行逻辑拆解
你给出的代码实际执行逻辑是这样的:
- 父类
Polygon的构造参数加了var修饰,因此noOfSides自动成为Polygon的公共可变成员变量。 - 子类
Square的构造参数noOfSides没有加var/val,仅作为临时参数,实例化Square(4)时,这个临时参数值4被传给父类构造,把父类的noOfSides成员初始化为4。 Square内部定义的noOfSideVar是Square自己的成员变量,初始值为7。- main方法中修改
square1.noOfSides = 10,修改的是父类Polygon的成员变量,后续打印为10是正常表现。 - 修改
square1.noOfSideVar = 50修改的是Square自己的成员变量,后续打印为50也符合预期。
补充验证
你可以在Square的area方法中增加一行赋值代码:
fun area(): Int { noOfSides = 100 // 直接修改父类继承的成员 return noOfSides * noOfSides }
调用area方法后再打印square1.noOfSides,会发现输出变为100,足以证明noOfSides在Square内部是可修改的。
如果你真的想让Square拥有自己的构造参数成员,可以给构造参数加var修饰:
class Square(var noOfSides: Int) : Polygon(noOfSides)
此时Square会定义一个和父类同名的成员变量,在Square内部访问noOfSides默认优先访问自身的成员,要访问父类的成员需要加super.noOfSides前缀。
内容的提问来源于stack exchange,提问作者user16537655
相关产品推荐
相关产品推荐

