关于学习Kotlin子类继承父类,成员属性Override时候需要注意的问题

最近在学习Kotlin这门语言,作为一个java程序员兼android程序员,Kotlin又在17年强势被google推崇为android官方开发语言之一,这就意味着,过去基于java语言的android开发人员,很有必要去掌握Kotlin这门语言,当然我这里不去谈论Kotlin如何,今天这个博客主要就是记录一下在学习Kotlin【继承-覆盖】这一节的时候遇到的一个特性,想做个记录,记录的主要原因是我今天遇到的这个问题,在很多入门学习帖子和博客都没有提及到这个特性。


首先,我们先声明一个基类:

package zhg.extend.demo

open class Person{
	open var nickname:String?=null
	get() =field?:"二狗子"
	set(value){
		field = value
	}
	open var name:String?=null
	get() =field?:"无名英雄"
	set(value){
		field = value
	}
	open var age:Int=0
	get() =field
	set(value){
		field = value
	}
	
	constructor(name:String?,age:Int){
				this.age = age
		this.name = name
	}
	
		constructor(name:String?,age:Int,nickname:String?):this(name,age){
		this.nickname = nickname
	}

	
	open fun say(){
		println("Hello! my name is ${this.name} , i'm ${this.age} years old, my nickname is ${this.nickname}")
	}
}

很明显,基类Person中的成员都被声明为open,基类本身也被修饰为open,说明这个基类是可以被继承的,其成员都是可以被Override的(至于为什么要用open来修饰,以及其他基础地方就不再复述了)。

OK,很简单,我们直接去继承Person,覆盖他的成员属性和函数,如下:

package zhg.extend.demo;


class Student : Person {
			override var nickname:String?=null

	override var name:String?=null

	override var age:Int=0

	constructor(name: String?, age: Int) : super(name, age) {
	}

	constructor(name: String?, age: Int, nickname: String?) : super(name, age,nickname) {
	}

	override fun say() {
		println("Hello! my name is ${this.name} , i'm ${this.age} years old, my nickname is ${this.nickname}")
	}
}

	fun main(args: Array<String>) {
		var student = Student( "太平公主",20,"唐朝公主")
		student.say()
	}

上面的代码很简单,直接继承了Person这个类,成员属性和函数都Override了,可以看到成员属性和函数都使用override来修饰了。


我们在main方法里面测试,看到的结果是

Hello! my name is 太平公主 , i'm 20 years old, my nickname is 唐朝公主


当然这是我想看到结果,但是在这之前,我的代码和前面贴出的代码有一个非常非常细微的差别,代码如下:

package zhg.extend.demo

open class Person{
	open var nickname:String?=null
	get() =field?:"二狗子"
	set(value){
		field = value
	}
	open var name:String?=null
	get() =field?:"无名英雄"
	set(value){
		field = value
	}
	open var age:Int?=0
	get() =field?.toInt()?:100
	set(value){
		field = value
	}
	
	constructor(name:String?,age:Int?){
				this.age = age
		this.name = name
	}
	
		constructor(name:String?,age:Int?,nickname:String?):this(name,age){
		this.nickname = nickname
	}

	
	open fun say(){
		println("Hello! my name is ${this.name} , i'm ${this.age} years old, my nickname is ${this.nickname}")
	}
}


package zhg.extend.demo;


class Student : Person {
	override var nickname:String?=null

	override var name:String?=null

	override var age:Int?=0

	constructor(name: String?, age: Int?) : super(name, age) {
	}

	constructor(name: String?, age: Int?, nickname: String?) : super(name, age,nickname) {
	}

	override fun say() {
		println("Hello! my name is ${this.name} , i'm ${this.age} years old, my nickname is ${this.nickname}")
	}
}

	fun main(args: Array<String>) {
		var student = Student( "太平公主",20,"唐朝公主")
		student.say()
	}

我打印的结果一直是

Hello! my name is 太平公主 , i'm 0 years old, my nickname is 唐朝公主


你会觉得很奇怪,为什么只有age这个属性没有打印出20?

查阅了相关官方文档和一些国内一些博客和帖子都没说出这两种写法的区别。


然后后面还发先,在上面的代码基础上,将子类Student中的age属性写成如下方式,赋初值为null,就能达到理想的结果。

override var age:Int?=null

至目前为止还是没有找到比较权威的和官方的解释和说明,希望有大牛看到之后,有相关的信息可以告知一升。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值