郴州网站建设公司哪家好,设计教育培训,php源码网站安装,郑州男科Kotlin是一个宣称与Java兼容性较好的语言#xff0c;但在接触后发现一些技术还是有“概念上”的冲突#xff0c;本文就记录下两者对象的Field#xff08;中文的说法有字段、域、属性、成员变量#xff0c;下文若出现这些表达#xff0c;指的都是这个东西#xff09;在继承…Kotlin是一个宣称与Java兼容性较好的语言但在接触后发现一些技术还是有“概念上”的冲突本文就记录下两者对象的Field中文的说法有字段、域、属性、成员变量下文若出现这些表达指的都是这个东西在继承中的不同表现。
Java中Field在继承中的表现
首先来看一段简单的程序
public class FieldInheritDemo {public static void main(String[] args) {Child child new Child();Parent parent child;System.out.println(child.a - parent.a);// 8-1child.a 88;System.out.println(child.a - parent.a);// 88-1parent.a 11;System.out.println(child.a - parent.a);// 88-11System.out.println(child.b - parent.b);// 9-2child.b 99;System.out.println(child.b - parent.b);// 99-2
// parent.b 22; //error: 不能对final变量赋值parent.printParent();// 11-2-11-2-88-99child.printChild();// 88-99-88-99-11-2}
}class Parent {public int a 1;public final int b 2;public void printParent() {System.out.println(a - b - this.a - this.b - ((Child) this).a - ((Child) this).b);}
}class Child extends Parent {public int a 8;public int b 9;public void printChild() {System.out.println(a - b - this.a - this.b - super.a - super.b);}
}
从输出结果来看Java的域有“遮蔽”的现象但是没有“覆盖”或“重写”的现象。具体引用的是父类的域还是子类的域取决于变量的类型而非对象的实际类型。this虽然是动态变量但是在Parent中它仍然是this。
Kotlin中Field在继承中的表现
同样来看一段和上面相似的程序
fun main(args: ArrayString) {val child: Child Child()val parent: Parent childprintln(${child.a}-${parent.a})// 8-8child.a 88println(${child.a}-${parent.a})// 88-88parent.a 11println(${child.a}-${parent.a})// 11-11println(${child.b}-${parent.b})// 9-9child.b 99;println(${child.b}-${parent.b})// 99-99
// parent.b 22; //error: 不能对val变量赋值parent.printParent()// 11-99-11-99-11-99child.printChild()// 11-99-11-99-1-2
}open class Parent {open var a: Int 1open val b: Int 2fun printParent() {println($a-$b-${this.a}-${this.b}-${(this as Child).a}-${(this as Child).b})}
}class Child : Parent() {override var a: Int 8override var b: Int 9;fun printChild() {println($a-$b-${this.a}-${this.b}-${super.a}-${super.b})}
}Kotlin中的输出结果来看“遮蔽”、“覆盖”现象都存在跟方法一样其实只要看字节码就可以发现对Field的读写都是调方法比如child.a 88这行字节码中就包含INVOKEVIRTUAL Parent.setA (I)V。
但是Kotlin中有两个需要注意的点
super的行为还是和Java类似并非Parent.setA之类的过程调用。当open和val同时修饰一个域的时候这个域可能会变例如上面parent.b我们没法对其赋值但是它的值却一直在变。没错不可变的值看上去变了。。。我很不喜欢这点设计用的时候当心