再谈Java中的覆盖(Overriding)与重载(Overloading)
2018-03-06 18:59
459 查看
在 Overriding vs Overloading in Java 中,我们简单介绍了Java中的Overriding 与 Overloading ,下面我们就此话题继续探讨:
问题一:什么是静态绑定?
答: 在JAVA源码编译阶段,JVM将方法调用与实际方法进行绑定的过程,这就是静态绑定,我们常见的方法重载绑定( method Overloading binding )就是静态绑定。
问题二:什么是动态绑定?
答: 覆盖方法绑定(Binding of overridden methods)就是我们常见的动态绑定,即编译阶段只确定引用类型对象,运行时生成实际对象类型,并将对象引用指向运行时生成对象的内存堆地址。
问题三:你可以 override静态方法么?
答案:否,static方法属于类方法,属于类级别,而非对象实例级别,类方法是在类的加载机制的编译阶段就会执行的方法,我们上一章说过,Overriding涉及一个运行时概念,即我们常见的动态绑定机制,所以我们是无法通过Override静态方法来达到预期效果的。当然,如果你在子类中Override父类中相同方法签名的方法,编译期是不会报错的,但是却无法得到预期的Overriding行为的,下面我们示例说明:
父类 Dog 中定义静态方法 eat
子类 Hound 中 Override 父类中的 eat 方法
验证对静态方法的 Override的效果
执行结果如下:
从上面的执行结果我们可以看到,对静态方法的Override并没有达到预期效果,这就是我们常见的方法隐藏 method hiding
问题四:可以覆盖(Override)私有(private)方法和final方法么?
答:私有方法(private)对子类不可见,因此,你无法覆盖私有方法,final关键词修饰的方法或变量表明方法或变量不可变,即你无法重新修改目标对象,因此你无法覆盖(Override)方法
问题五:什么是协变返回类型?
答:如果子类中覆盖(overrides)了父类中的相关方法,那么子类方法的返回类型可以是父类方法中返回类型的子类,下面我们代码示例:
父类 Base 方法 m 返回类型为A,子类 Sub 覆盖了方法 m,但返回类型B(B是A的子类),这就是我们Overriding中的协变返回类型。
运行结果:
问题六:以下代码输出结果?
输出
子类覆盖(Override)方法抛出的异常《= 父类方法抛出的异常,即子类抛出的异常可以缩小或不抛出异常,但不能新增或者扩大 **checked
Exception**
问题七:以下代码输出结果?
结果:
子类覆盖(Override)方法的访问修饰符 》= 父类方法访问修饰符
覆盖(Overriding)使用规范
重载(Overloading)使用规范
原文链接:https://java2blog.com/method-overloading-and-overriding-interview-questions-in-java/
问题一:什么是静态绑定?
答: 在JAVA源码编译阶段,JVM将方法调用与实际方法进行绑定的过程,这就是静态绑定,我们常见的方法重载绑定( method Overloading binding )就是静态绑定。
问题二:什么是动态绑定?
答: 覆盖方法绑定(Binding of overridden methods)就是我们常见的动态绑定,即编译阶段只确定引用类型对象,运行时生成实际对象类型,并将对象引用指向运行时生成对象的内存堆地址。
问题三:你可以 override静态方法么?
答案:否,static方法属于类方法,属于类级别,而非对象实例级别,类方法是在类的加载机制的编译阶段就会执行的方法,我们上一章说过,Overriding涉及一个运行时概念,即我们常见的动态绑定机制,所以我们是无法通过Override静态方法来达到预期效果的。当然,如果你在子类中Override父类中相同方法签名的方法,编译期是不会报错的,但是却无法得到预期的Overriding行为的,下面我们示例说明:
父类 Dog 中定义静态方法 eat
class Dog { public void bark() { System.out.println("woof"); } public void bark(int num) { for (int i = 0; i < num; i++) { System.out.println("woof"); } } **static void eat(){ System.out.println("Dog eat"); }** }
子类 Hound 中 Override 父类中的 eat 方法
class Hound extends Dog { public void bark() { System.out.println("bowl"); } static void eat(){ System.out.println("Hound eat"); } }
验证对静态方法的 Override的效果
public class OverrideAndOverload { public static void main(String[] args) { Dog a = new Hound(); a.bark(); a.bark(1); **a.eat();** } }
执行结果如下:
bowl woof Dog eat
从上面的执行结果我们可以看到,对静态方法的Override并没有达到预期效果,这就是我们常见的方法隐藏 method hiding
问题四:可以覆盖(Override)私有(private)方法和final方法么?
答:私有方法(private)对子类不可见,因此,你无法覆盖私有方法,final关键词修饰的方法或变量表明方法或变量不可变,即你无法重新修改目标对象,因此你无法覆盖(Override)方法
问题五:什么是协变返回类型?
答:如果子类中覆盖(overrides)了父类中的相关方法,那么子类方法的返回类型可以是父类方法中返回类型的子类,下面我们代码示例:
父类 Base 方法 m 返回类型为A,子类 Sub 覆盖了方法 m,但返回类型B(B是A的子类),这就是我们Overriding中的协变返回类型。
class A { } class B extends A { } class Base { public A m() { System.out.println("In BaseClass method"); return new A(); } } class Sub extends Base { public B m() { System.out.println("In SubClass method"); return new B(); } } public class CovariantReturnTypeTest { public static void main(String[] args) { Base b = new Sub(); b.m(); } }
运行结果:
In SubClass method
问题六:以下代码输出结果?
import java.io.IOException; public class MethodOverrdingTestMain { public static void main(String[] args) { B b = new B(); try { b.method(); } catch (Exception e) { e.printStackTrace(); } } } class A { public void method() **throws IOException** { } } class B extends A { public void method() **throws Exception** { } }
输出
**compile time error**
子类覆盖(Override)方法抛出的异常《= 父类方法抛出的异常,即子类抛出的异常可以缩小或不抛出异常,但不能新增或者扩大 **checked
Exception**
问题七:以下代码输出结果?
class Base { **public** A m() { System.out.println("In BaseClass method"); return new A(); } } class Sub extends Base { **protected** B m() { System.out.println("In SubClass method"); return new B(); } } public class CovariantReturnTypeTest { public static void main(String[] args) { Base b = new Sub(); b.m(); } }
结果:
compiler time error
子类覆盖(Override)方法的访问修饰符 》= 父类方法访问修饰符
覆盖(Overriding)使用规范
方法参数 | 完全一致 |
---|---|
返回类型 | 保持一致或者协变返回类型 |
访问修饰符 | 子类访问修饰符大于等于父类访问修饰符 |
异常 | 子类异常必须小于父类异常 |
构造方法 | 无法覆盖 |
静态方法 | 无法覆盖 |
final方法 | 无法覆盖 |
参数个数 | 重载方法参数个数不同 |
---|---|
参数类型 | 重载方法参数类型不同 |
返回类型 | 可以修改返回类型,但需注意重载情况不能出现方法签名相同但返回类型不同 |
参数顺序 | 如果各个参数数据类型不同,那么参数顺序变化也是合法的方法重载 |
构造函数 | 可以重载 |
相关文章推荐
- Java重载overloading与重写(覆盖)overriding
- Java基础--重写(Overriding,覆盖)-重载(Overloading)
- java中重载(Overloading)和重写(Overriding)
- JAVA基础(一)——重载(Overloading)与重写(Overriding)的区别
- java 方法的覆盖(overriding)与重载(override)
- 常见Java面试题 – 第三部分:重载(overloading)与重写(overriding)
- 黑马程序员 【】java学习之路——重写(Overriding)、重载(Overloading)、多态的简单总结
- java中重载(Overloading)、重写(Overriding)、重定义(redefinition)
- java方法的重载(overloading)和覆盖(override)
- java中的重载(overriding)跟重写(overloading)理解
- Java 重写(Overriding)和重载(Overloading)
- Java中的重写(overriding)和重载(overloading)
- java中重载Overriding与重写Overloading的区别
- Polymorphic Java Override and Overloading, 多态,对象的重载与覆盖
- Java学习笔记之重写(Overriding)与重载(Overloading)
- java中的方法覆盖(Overriding)和方法重载(Overloading)
- 常见Java面试题 – 第三部分:重载(overloading)与重写(overriding)
- java语言中方法重载overloading和方法重写(覆写)overriding的区别
- 【转】常见Java面试题 – 第三部分:重载(overloading)与重写(overriding)
- java中的方法覆盖(overriding)和方法重载(overloading)