Java 重写和隐藏
来源:互联网 发布:wings liquid知乎 编辑:程序博客网 时间:2024/05/21 17:42
1、编译时类型和运行时类型
Java的引用变量有两个类型,一个是编译时类型,一个是运行时类型
编译时类型:由声明该变量时使用的类型决定
运行时类型:由该变量指向的对象类型决定
如果编译时类型和运行时类型不一致,会出现所谓的多态。因为子类其实是一种特殊的父类,因此java允许把一个子类对象直接赋值给一个父类引用变量,无须任何类型转换,或者被称为向上转型,由系统自动完成。
如 Father f = new Son(); Son是Father的子类
引用变量f就会出现编译时类型和运行时类型不一致的情况 编译时是Father类型的 运行时是Son类型的
当变量的编译时类型和运行时类型不一致时,通过变量访问它所引用的对象的实例时,该实例变量的值由声明该变量的类型决定。
通过变量访问它所引用的对象的方法时,该方法的行为由所引用的对象实际类型所决定。
2、隐藏和覆盖
覆盖:子类重写父类的方法,要求方法名和参数类型完全一样(参数不能是子类),返回值和异常比父类小或者相同(即为父类的子类),访问修饰符比父类大或者相同。
覆盖是对于实例方法而言的
方法不能交叉覆盖:子类实例方法不能覆盖父类的静态方法;
子类的静态方法也不能覆盖父类的实例方法(编译时报错)
隐藏:父类和子类拥有相同名字的属性或者方法( 方法隐藏只有一种形式,就是父类和子类存在相同的静态方法)时,父类的同名的属性或者方法形式上不见了,实际是还是存在的。
隐藏是对于静态方法和成员变量(静态变量和实例变量)而言的
(1)当发生隐藏的时候,声明类型是什么类,就调用对应类的属性或者方法,而不会发生动态绑定
(2) 属性只能被隐藏,不能被覆盖
(3)变量可以交叉隐藏:子类实例变量/静态变量可以隐藏父类的实例/静态变量
3、隐藏和覆盖的区别
(1)被隐藏的属性,在子类被强制转换成父类后,访问的是父类中的属性
在无强制转换时子类要访问父类的属性使用super关键字
(2)被覆盖的方法,在子类被强制转换成父类后,调用的还是子类自身的方法
子类要是想访问父类的方法,可以使用super关键字
RTTI(run time type identification,运行时类型检查)
RTTI只针对覆盖,不针对隐藏:因为覆盖是动态绑定,是受RTTI约束的,隐藏不受RTTI约束
运行时类型为引用变量所指向的对象的类型,编译时类型是引用变量自身的类型
4、常见的笔试面试题
- public class Test {
- public static void main(String[] args) {
- Circle circle = new Circle();//本类引用指向本类对象
- Shape shape = new Circle();//父类引用指向子类对象(会有隐藏和覆盖)
- System.out.println(circle.name);
- circle.printType();
- circle.printName();
- //以上都是调用Circle类的方法和引用
- System.out.println(shape.name);//调用父类被隐藏的name属性
- shape.printType();//调用子类printType的方法
- shape.printName();//调用父类隐藏的printName方法
- }
- }
- class Shape {
- public String name = "shape";
- public Shape(){
- System.out.println("shape constructor");
- }
- public void printType() {
- System.out.println("this is shape");
- }
- public static void printName() {
- System.out.println("shape");
- }
- }
- class Circle extends Shape {
- public String name = "circle"; //父类属性被隐藏
- public Circle() {
- System.out.println("circle constructor");
- }
- //对父类实例方法的覆盖
- public void printType() {
- System.out.println("this is circle");
- }
- //对父类静态方法的隐藏
- public static void printName() {
- System.out.println("circle");
- }
- }
- 运行结果:
- shape constructor
- circle constructor
- circle
- this is circle
- circle
- shape
- this is circle
- shape
- Java 重写和隐藏
- Java中的重载、重写和隐藏
- java中的重载、重写和隐藏
- java重载和重写以及隐藏
- 隐藏和重写
- 重载、隐藏和重写
- C#和Java 方法重写和覆盖隐藏的区别
- Java中的重载、重写和隐藏(续)
- java中重写(Overriding)和隐藏(Hiding)方法问题
- 关于java的重写和隐藏的学习笔记。
- Java和C++中“隐藏/覆盖/重写/重载” 的区别
- Java中的重写与隐藏
- 重写和重载与隐藏
- C++的重写和隐藏
- C#中的隐藏和重写
- 重写(Overriding)和重载(Overloading)和隐藏
- Java炸弹:重载、重写、隐藏、遮蔽、遮掩
- 重载、重写(覆盖)、隐藏的区别--Java
- chmod chmod命令
- ServletContext作用功能详解
- 行为日志分析思路与想法
- oracle中的视图
- JVM中的逃逸分析
- Java 重写和隐藏
- 在火狐安装restful调试步骤
- 请求的链式处理——职责链模式(四)
- Exchange如何将邮件转发给外部邮件地址
- Activiti 错误结束事件和边界错误事件
- redis-复制原理-哨兵模式
- 深入理解javascript原型和闭包(10)——this
- openstack 卸载/挂载 系统卷
- python egg的构建