Java 的覆写字段回顾|学习笔记

简介: 快速学习 Java 的覆写字段回顾。

开发者学堂课程【Scala 核心编程-基础Java 的覆写字段回顾】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/609/detail/8975


Java 的覆写字段回顾

 

内容介绍

一、覆写字段

二、Java 中为什么字段不能被重写

三、如何访问隐藏字段

四、小结

五、回顾-java 另一重要特性:动态绑定机制

六、总结

 

一、覆写字段

1.基本介绍

Scala 中,子类改写父类的字段,称为覆写/重写字段。

覆写字段需使用 override 修饰。

前面研究了方法的重写,在 java 中有方法的重写。

讲到 scala 的覆写字段有必要了解 Java 中的覆写。

2.回顾:

在 Java 中只有方法的重写,没有属性/字段的重写,准确的讲,是隐藏字段代替了重写。参考:Java 中为什么字段不能被重写.doc[字段隐藏案例]。

只有将 Java 中为什么字段不能被重写讲清楚了后,学习 scala 覆写字段才会特别深刻,而且会感觉 scala 的机制会解决很多容易混淆的地方。

 

二、Java 中为什么字段不能被重写

案例:新建两个 Sub 对象,一个指向 Sub 类型的引用,一个指向 Super 类型的引用。

class Super {  //超类

String s = "Super";

}

class Sub extends Super {  //子类 sub 继承了 super

String s = "Sub";

这里都有一个 s

}

public class Fieldoverriding { //Fieldoverriding

public static void main(String[ ]args) { //主函数 main

Sub c1=new Sub();  //创建 c1为子类对象的引用

System out -print ln(c1.s);   //(c1.s)输出 sub

Super c2=new Sub():   //新的子类对象 sub 给父类 c2引用

Syst em .out -print ln(c2.s);  //(c2.s)输出 super

}

这里体现出字段并没有被真正覆写 s,只是在子类里面隐藏了。

这里有几个重要的原则,如果以前 java 没学习到位的话,这一节要认真听。

创建一个 class 类型的文件名为 javaFieldoverride,写入:

package com. atguigu. chapter07. myextends ;

public class JavaFiledoverride {

public static void main(String[ ] args) {

//创建两个对象

Sub2 c1 = new Sub2();

System. out . println(c1.s);   //输出 sub

Super2 C2 = new Sub2( );

System. out. println(c2.s);  //输出 super

} // 主方法

class Super2 {

String S = " super" ;

}

class Sub2 extends Super2 {

string S = "sub" ;    //子类

运行:

D: \program\jdk8\bin\java

sub

super

Process finished with exit code 0

通过这段简单的代码想说的问题是创建了两个 sub 对象,但是为什么第二个对象打印出来的结果是“super”呢?

java 官方提供的 tutorial 有一段关于隐藏字段的明确定义:

Within a class, a field that has the same name as a field in the superclass hides thesuperclass’s field, even if their types are different. Within the subclass, the field in the superclasscannot be referenced by its simple name. Instead, the field must be accessed through super.Generally speaking, we don’t recommend hiding fields as it makes code difficult to read.

上面这段解释中可以看出成员变量不能像方法一样被重写。

在 java 中当一个子类定义了一个跟父类相同名字的字段,子类就是定义了一个新的字段。

这个字段在父类中被隐藏的,是不可重写的。

也就是说在它的底层里,子类有一部分,父类有一部分,它们之间是分开的。

既然是隐藏的那么就能想办法访问到。

 

三、如何访问隐藏字段

1采用父类的引用类型,这样隐藏的字段就能被访问了,像上面所给出的例子一样。

2将子类强制类型转化为父类类型,也能访问到隐藏的字段。

比如在以上代码的基础上写入:

System. out. println(((Super2)c1).s);

通过强转,仍然可以访问到被隐藏的字段。

 

四、小结

主要涉及到 java 里面一个字段隐藏的概念,父类和子类定义了一个同名的字段,不会报错。

但对于同一个对象,用父类的引用去取值(字段),会取到父类的字段的值,用子类的引用去取值(字段),则取到子类字段的值。

在实际的开发中,要尽量避免子类和父类使用相同的字段名,否则很容易引入一些不容易法现的 bug

结论:

1、对于同一个对象,用父类的引用去取值(字段),会取到父类的字段的值

2、用子类的引用去取值(字段),则取到子类字段的值。

 

五、回顾-java 另一重要特性:动态绑定机制

创建一个 alcss 类型的文件名为 javadaynamicbind 写入:

package com. atguigu. chapter07. myextends;

public class JavaDaynamicBind {

public static void main(String[ ] args) {

}

class AA {

public int i= 10;

public int sum() {

return getI()+ 10;

}

public int sum1() {

return i+ 10;

public int getl() {

return i;

}

class BB extendsAA {

public inti= 20;

public int sum() {

return i+ 20;

}

public int getl(){

return i;

}

public int sum1() {

returni+ 10;

}

将代码:AA obj= new BB();

System.out.println(obj.sum());

System.out.println(obj.sum1());

放到主函数里面,在这个数据空间里,将一个子类的对象地址,交给了一个 AA(父类的)引用。

流程是先看一下 BB,因为现在 obj 在内存空间是个子类,所以在调用方法的时候会先找自己有没有方法,发现有,所以:

System.out.println(obj.sum());应该返回40

System.out.println(obj.sum1());应该返回30

运行:

D: \program\jdk8\bin\java

40

30

Process finished with exit code 0

没有问题。

改进:

public int sum() {

return i+ 20;

}

注销,此时 System.out.println(obj.sum());会输出30

如果将 sum 注销,找的就是上面的方法,方法里又调用了 getI,它返回的应该是20

public int sum1() {

returni+ 10;

}

注销,此时 System.out.println(obj.sum1());会输出20

调用的是上面的 sum1,这时I返回的是10

执行:

D: \program\jdk8\bin\java

30

20

Process finished with exit code 0

这道题的关键,只要知道两个结论就可以了,以前讲过 Java 的动态绑定机制的小结:

1、如果调用的是方法,则 jvm 机会将该方法和对象的内存地址绑定

2、如果调用的是一个属性,则没有动态绑定机制,在哪里调用就返回对应的值

所以刚才因为把 sum 去掉了,调用的时候是调用的上面 AA 的 sum。

调用 getI,是调用方法,调用方法就会与内存地址绑定。

因为是 BB,所以调用的是下面 BB 的 getI,返回的I又不是动态绑定的,就会返回20,所以整个结果就是20+10

知道了 jvm 机底层运行机制后,学习 Scala 的覆写字段就会很轻松,很明白它的规则。

 

六、总结

本节主要讲解了覆写字段相关内容:

1、基本介绍:

Scala 中,子类改写父类的字段,我们称为覆写/重写字段。覆写字段需使用 override 修饰。

2、回顾:

在 Java 中只有方法的重写,没有属性/字段的重写,准确的讲,是隐藏字段代替了重写。参: Java 中为什么字段不能被重写.doc [字段隐藏案例]。

3、回顾-Java 另一重要特性:动态绑定机制

动态绑定的机制:

java 的动态绑定机制的小结

1如果调用的是方法,则 Jvm 机会将该方法和对象的内存地址绑定

2如果调用的是一个属性,则没有动态绑定机制,在哪里调用,就返回对应值

相关文章
|
6月前
|
Java 编译器 开发工具
Java基础学习笔记——idea篇
JDK由JRE(包含JVM和核心类库)和开发工具箱(如javac编译器和java运行工具)组成。Java项目结构包括Project、Module、Package和Class。IDEA快捷键包括:生成main方法(main psvm)、复制代码(Ctrl+D)、删除代码(Ctrl+Y/X)、格式化代码(Ctrl+Alt+L)、重命名(Shift+F6)等。
51 0
|
6月前
|
监控 负载均衡 Dubbo
|
3月前
|
存储 Java
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
|
2月前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
从Java环境的搭建到实际代码的编写,从基本用法的讲解到底层原理的剖析,深度解析Java基础知识。本文是《Java学习路线》专栏的起始文章,旨在提供一套完整的Java学习路线,覆盖Java基础知识、数据库、SSM/SpringBoot等框架、Redis/MQ等中间件、设计模式、架构设计、性能调优、源码解读、核心面试题等全面的知识点,并在未来不断更新和完善,帮助Java从业者在更短的时间内成长为高级开发。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
|
2月前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
本文是Java基础的进阶篇,对异常、集合、泛型、Java8新特性、I/O流等知识进行深入浅出的介绍,并附有对应的代码示例,重要的地方带有对性能、底层原理、源码的剖析。适合Java初学者。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
|
29天前
|
算法 Java Linux
java制作海报一:java使用Graphics2D 在图片上写字,文字换行算法详解
这篇文章介绍了如何在Java中使用Graphics2D在图片上绘制文字,并实现自动换行的功能。
76 0
|
1月前
|
Java 数据安全/隐私保护
java学习笔记(基础习题)
java学习笔记(基础习题)
31 0
|
1月前
|
Java 程序员 开发工具
java学习笔记
java学习笔记
34 0
|
2月前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(高级篇)
本文是“Java学习路线”中Java基础知识的高级篇,主要对多线程和反射进行了深入浅出的介绍,在多线程部分,详细介绍了线程的概念、生命周期、多线程的线程安全、线程通信、线程同步,并对synchronized和Lock锁;反射部分对反射的特性、功能、优缺点、适用场景等进行了介绍。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(高级篇)
|
3月前
|
SQL druid Java
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
54 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
下一篇
无影云桌面