当前位置: 首页 > news >正文

Java和Kotlin的Field在继承中的不同表现

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: Array<String>) {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中有两个需要注意的点:

  1. super的行为还是和Java类似,并非Parent.setA之类的过程调用。
  2. openval同时修饰一个域的时候,这个域可能会变,例如上面parent.b,我们没法对其赋值,但是它的值却一直在变。(没错,不可变的值看上去变了。。。我很不喜欢这点设计,用的时候当心)
http://www.lryc.cn/news/158601.html

相关文章:

  • MySQL 子查询
  • Ubuntu离线或在线安装CMake
  • 后端面试话术集锦第 十七 篇:MySQL面试话术
  • < 文件资源管理器 > 和 < 此电脑 > 有什么区别?
  • 线上问诊:可视化展示
  • 如何选择合适的HTTP代理服务器
  • Car Window Control Reset
  • 序列号序列号
  • SSM(Spring-Mybatis-SpringMVC)
  • MySQL——数据的删除以及MySQL中的约束
  • 静态路由 网络实验
  • 数据结构-01 数据结构基本概念,算法时间复杂度,空间复杂度
  • 【Redis】Bitmap 使用及应用场景
  • C#,数值计算——用于积分函数与方法的Stiel类的计算方法与源程序
  • 报错:为什么数组明明有内容但打印的length是0
  • go gin gorm连接postgres postgis输出geojson
  • 4. Java 的线程安全机制之`volatile`
  • ​Vue + Element UI前端篇(二):Vue + Element 案例 ​
  • Qt5中connect信号槽无效问题 C++
  • 服务端 TCP 连接的 TIME_WAIT 过多问题的分析与解决
  • 【Unity3D赛车游戏优化篇】【十】汽车粒子特效和引擎咆哮打造极速漂移
  • 肖sir__设计测试用例方法之编写测试用例12
  • Android 11.0 ota升级之Systemui下拉状态栏quick_settings_tiles_default值减少时更新的功能实现
  • Android Studio中创建java项目
  • 冠达管理:“旺季”来临,煤炭板块走高,云煤能源、陕西黑猫涨停
  • 【EI检索】第四届公共卫生与数据科学国际学术研讨会(ICPHDS 2023)
  • 对时序数据进行分类与聚类
  • Win10如何找回图片查看器
  • 【脑机接口】基于运动想象的康复指导在脑卒中偏瘫患者中的应用
  • vue-cli中vuex下$store”未在实例上定义