开发者学堂课程【Scala 核心编程-基础:覆写字段注意事项和细节说明1】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/609/detail/8977
覆写字段注意事项和细节说明1
覆写字段的注意事项和细节:
1、def 只能重写另一个 def(即:方法只能重写另一个方法)
2、val 只能重写另一个 val 属性或重写不带参数的 def[案例+分析]
如果加入了 def,就不存在重写的概念了。
在 scala 里面属性方法重写在一定程度上是等价的。
class AAAA {
var name: String = ""
}
class BBBB extends AAAA {
override val name: String =“
jj
"
}
这段代码正确吗?
上面有 AAAA 的父类,下面有 BBBB,上面是 var,下面是 val 而且还有 override,这段代码是不通过的。
如果这段代码可以,那么上面的 name 会生成两个公开方法,一个是 name 设置的方法,一个是name获取的方法,下面是 val,所以只能生成一个 get方 法。那么就会出现:
假如有一个 BBBB 的对象,在得对象的时候用的是 BBBB 的方法,设置的时候用的是父类的方法,就很容易造成逻辑上的混乱。
创建一个 object 类型的文件名为 FiledOverrideDetail,将代码引入:
package com. atguigu. chapter07. myextends
object FiledoverrideDetail {
def main(args: Array[string]): Unit = {
println(" 'xx
x
" )
}
class AAAA {
var name: String = ""
}
class BBBB extends AAAA {
override val name: String =“
jj
"
}
运行看会不会报错,有些时候在 Scala 里语法没有报错,但是执行的时候就会出现问题:
Error:(13, 17) overriding variable name in class AAAA of type String;
value name cannot override a mutable variable
override val name: String =
“jj”
如果代码成立:
var name: String = ""底层会生成 public name()和 public name $eq()
override val name: String =“jj"底层会生成 public name() 这样就把上面的方法覆写了。
那么就会出现,比如:val bbbb = new BBBB,假如程序员在使用 bbbb.name=“jack”相当于调用了父类的name $eq()
在读取时:println(bbbb.name)相当于调用了子类的 name(),这样编译器就会出现数据设置和数据获取不一致。
class A {
def sal(): Int = {
return 10
}}
class B extends A{
override val sal :Int = 0
}
这段代码是可以的,因为学习完方法的重写就要清楚它的本质,override val sal :Int = 0
它的本质是会在 B 里面生成一个 public 类型的 get 方法,就可以形成重写的关系,也就是这里看起来是属性,但是属性居然把父类的方法重写了,所以 Scala 就有一个和 java 思路上的转变。
说明val只能重写另外一个 val 属性。如果 val age 改成 var 就会报错。
新建一个类型为 object 类型的文件名为
ScalaFieldoverridedetail02,将代码引入:
package com. atguigu. chapter07. myextends
object ScalaFieldoverrideDetail02 {
def main(args: Array[string]): Unit = {
println(" 'xx
x
" )
}
class AAAAA {
def sal(): Int = {
return 10
}}
class BBBBB extends AAAAA{
override val sal :Int = 0
}
代码没有任何问题,运行:
D: \program\jdk8\bin\java
X
xx
Process finished with exit code 0
现在创建一个bbbbb的对象:
val bbbbb
=
new BBBBB( )
println(bbbbb. sal)
因为是动态绑定机制,所以返回的还是 override val sal :Int = 0的0,底层有一个 public sal
运行:
D: \program\jdk8\bin\java
XXx
0
Process finished with exit code 0
返回的是0.
假如现在有一个 b2:
valb2:AAAAA =new BBBBB( )
println("b2.sal=" +b2.sal())
虽然写的是 AAAAA,但是调用的还是 override val sal :Int = 0,因为有动态绑定机制所以返回的还是0。
运行:
D: \program\jdk8\bin\java
XXx
0
B2.sal
:0
Process finished with exit code 0
所以一定要考虑 scala 底层的机制。