无论实例对象的类型被定义成基类类型还是子类类型,都优先执行实例化目标类中的方法,若该类中无此方法,则往上寻找去执行基类的该方法
class Base{
def show():Unit = {
printf("Base")
}
}
class Sub extends Base{
override def show(): Unit = {
printf("Sub")
}
}
object Test {
def main(args: Array[String]): Unit = {
val sub:Sub = new Sub
sub.show()
}
}
上述代码基类和子类分别有一个show方法,子类对其进行了重写,最后的输出结果是打印了 Sub 字符串,可见Sub子类中的show方法得到了执行。关键的来了,即使 val sub:Sub = new Sub 这行改为了
var sub:Base = new Sub
最后打印结果依旧没变,可见印证了上述结论
然后对该段代码稍作修改,注释掉子类的 show 方法,再看一下结果
class Base{
def show():Unit = {
printf("Base")
}
}
class Sub extends Base{
/*override def show(): Unit = {
printf("Sub")
}*/
}
object Test {
def main(args: Array[String]): Unit = {
val sub:Sub = new Sub
sub.show()
}
}
这是发现打印结果变成了 Sub 字符串,这是因为子类中的确是没有该方法了,不得已去基类查找,最后执行基类的show方法
若基类子类的属性不存在覆盖行为,则方法对属性的获取是就近原则,若存在覆盖行为,则方法永远获取子类的属性
不存在覆盖的行为指属性都由 private 修饰,就近原则指基类的方法获取基类的属性,子类的方法获取子类的属性
class Base{
private val name = "Base"
def show():Unit = {
printf(this.name)
}
}
class Sub extends Base{
private val name = "Sub"
}
object Test {
def main(args: Array[String]): Unit = {
val sub:Base = new Sub
sub.show()
}
}
上述代码执行基类的show方法,由于name属性都被private修饰,不存在覆盖,采取就近原则,最后打印结果是基类的name值——”Base”
class Base{
val name = "Base"
def show():Unit = {
printf(this.name)
}
}
class Sub extends Base{
override val name = "Sub"
}
object Test {
def main(args: Array[String]): Unit = {
val sub:Base = new Sub
sub.show()
}
}
然后对其进行改写,使得name属性被覆写,这时发现虽然执行的还是基类的show方法,但是打印的是子类的name值——”Sub”,印证了这一结论
近期评论