【Scala·语法·笔记】1、为主构造器参数形成的字段,设置 protected;2、类中定义同名字段却不报错的坑

结论:
1,通过 protected[this],可以把主构造器参数形成的字段的访问级别,设置成受保护类型
class Person(protected[this] var age : Int) { }
 
2,特定条件下,类定义中存在同名字段,却不会报错。(隐隐感觉会在将来的某个时候弄个Bug出来搞死自己,千万要避免字段同名)
条件:a,主构造器参数,没有 val 或 var;b,类中,定义了同名、非私有字段
class Person(age : Int) { //age 前加 val 或 var。就会报错
protected[this] var age : Int = _ //不写访问级别,或 protected[this],不报错;pribate[this] 报错
}

class Student extends Person(7) {
def schoolAge {
println(if (age > 6) "School Age" else "Preschool")
}
}

object Person extends App {
val s = new Student
s.schoolAge
s.age //无法在类外访问,但可以在子类中访问
}

 
分析过程:
 
ps.    刚抱怨完学习效率不高,又忍不住来扣这么个细节的地方。(耳边响起了玉海老师的嘱咐“学习的内容很多,要抓重点啊!)
不过,在学习这个知识点时,有些意外收获。还是发出来跟大家交流一下。
 
       事情是从陈超老师讲“主构造器参数自动形成类的字段”开始的。其中,有个知识点是“加 val 或 var,则对应的字段为 public;不加,则为 private”,那如果需要这个字段为 protected 该怎么声明呢?情景如下:
class Person(age : Int){
}

class Student extends Person(20){
println(age) // 报错:Not Found。因为 age 是 Person 类的私有类型
}

object Person extends App {
val s = new Student
}

       那么,如何在子类中访问父类“不带 val 或 var 的主构造器参数形成的字段”呢?当然,可以把该字段从主构造器的参数列表中去掉,挪到类中声明。但,只样一来,还需要再定义一个方法,用于设置该字段的值。能否依然“在主构造器的参数列表中”,又能是 protected?
 
       我做了以下尝试:
1,直接在类中定义同名字段。
       但显然 1 个类里,有 2 个同名字段,是不正常的。可万万没想到“没 有 报 错”。而且,类里定义的同名 protected 字段,可以在子类中访问,但就是主构造器参数的值,没有传给该字段。这么做就没有意义了(还得声明个方法设置 age 的值)。
class Person(age : Int){
protected[this] var age : Int = 10
}

class Student extends Person(20){
println(age) // 10 //意外的是,居然没有报错
}

object Person extends App {
val s = new Student
}

2,直接在主构造器参数上设置访问级别,可以有效使用
class Person(protected[this] var age : Int) { //一定要写 protected[this]。如果只写 protected,依然可以在类声明之外访问,却 “没 有 提 示”
}

class Student extends Person(7) {
def schoolAge {
println(if (age > 6) "School Age" else "Preschool")
}
}

object Person extends App {
val s = new Student
s.schoolAge
s.age //无法在类外访问,但可以在子类中访问
}

 

0 个评论

要回复文章请先登录注册