Override(覆盖/复写)是面向对象多态的实现,是JVM运行期的特性, Overloading(重载)是编译期的特性.
首先我们来看看Override JVM中对overloading的描述是具有相同的方法签名,那么什么是相同的方法签名呢?
首先方法名称必须相同,然后方法的返回类型必须相同(1.对象类型的话,2.子类所返回的参数的类型也必须是父类返回的参数的相同类型或其子类,3.参数类型和顺序必须匹配4,子类要么不抛出异常,要么抛出相同异常或其父类方法抛出的异常的子类), 详细的描述及其代码如下:
接下来我们在看一下方法可见性及其其它方法关键字的影响.首先既然是override, 那么一个static 的方法是不允许覆盖的,接下来一个final 的方法也是不可以被覆盖的. 在然后,我们谈protected 关键字, 他表示对其子类可见. 无关键字(default)当前类所在包(package)可见, public任意包可见,private该类即将内部类可访问.
假如我们有class C extends class B, class B extends class A 且存在相同package中, class A,B,C都有相同方法签名method, 那么
如果class A 中public method(), 那么class B 和class C中的method 也必须都是public.
如果class A 中method(). 那么class B中method() 可以是default,或protected或public, class C中的method()依照class B中的顺序因该是default, 或 protected/public, 或public
如果class A 中protected method(), 那么class B 中必须是protected 或 public, 对应的class C 中应该是protected/public 或 public
所以static/final 不可以有override, 子类的可见性必须大于或等于父类的可见性,如果父类使用private,意味着这个方法被隐藏了,子类是无法访问和覆盖的
public class ParentClass {
void method1() {
try {
method2();
} catch (IOException e) {
e.printStackTrace();
}
}
protected void method2() throws IOException {
System.out.println("ParentClass - method2");
}
}
public class ChildClass extends ParentClass {
public void method2() {
System.out.println("ChildClass - method2");
}
}
public static void main(String[] args) {
ParentClass p = new ChildChildClass();
//ChildChildClass p = new ChildChildClass();
p.method1(); // 结果输出 => ParentClass - method2
}
1. 方法名相同..
2. 方法返回参数匹配->子类的返回类型必须是父类参数类型或其子类(这里是子类,不可运用原始类型,如父类是long,子类也必须返回long,不可以是int..)
public interface IParent {
ParentParam method4();
}
public class MyParentImplimplements IParent{
@Override
public ParentParam method4() {
return null;
}
}
public class MyParentImplimplements IParent{
@Override
public ChildParam method4() {
returnnull;
}
}
public interface IParent {
ChildParam method5();
}
public class MyParentImplimplementsIParent{
@Override
publicChildParam method5() {
return null;
}
}
下面的代码将会编译错误
public class MyParentImplimplements IParent{
@Override
publicParentParam method5() {
returnnull;
}
}
3. 参数类型的匹配->子类的参数类型必须也是父类参数类型,完全匹配
public interface IParent {
void method1(ParentParam parm);
}
下面代码编译错误
public class MyParentImplimplements IParent{
@Override
publicvoid method1(ChildParam parm) {
}
}
public interface IParent {
void method11(ChildParam parm);
}
下面代码编译错误
public class MyParentImplimplements IParent{
@Override
publicvoid method11(ParentParam parm) {
}
}
4. 异常类型的匹配-> ->子类的异常类型必须是父类参数类型或其子类 或者不抛出异常
public interface IParent {
void method2()throws IOException;
}
public class MyParentImplimplements IParent{
@Override
publicvoid method2(){
}
}
public class MyParentImplimplements IParent{
@Override
publicvoid method2()throws FileNotFoundException{
}
}
下面代码编译错误
public class MyParentImplimplements IParent{
@Override
publicvoid method2()throws Exception {
}
}
接着我们来看看Overloading,是指在一个类中可以允许有多个相同方法签名相同但参数类型不同的方法,即使顺序不一样。
如果我们有了intmethod(),就不可以有intmethod()throws Exception或longmethod()
如果我们有了 int method( int i, double b), 还可以有 int method( double b, int i)