Java重载、重写、覆盖、隐藏的总结

重载Overloading

发生要素如下:

1. 在同一作用范围内(同一个类,同一个接口)

2. 方法名必定相同

3. 形参组成不同(类型、个数均不相同 or 个数相同但类型不同 or 类型相同个数不同)

错误的认识:

1. 方法名相同,形参组成完全相同,返回类型不同也算重载(方法重载要求方法具有不同的签名:形参组成,而返回值并不算作签名内容,故不参与重载的选择)

2. abstract修饰必须存在才算重载方法(无所谓啊,修饰符惹谁了?)

abstract class AbstractBase {
    abstract void add();  
    abstract void add(int a);  //OK 
    void add(String b){} //OK
    int add(String b){} // NO!!!编译不通过
    protected void add(int a,int b){}
}

覆盖/重写/覆写(一个意思!)(Overriding/Overwrite)

发生要素如下:

1. 不同作用范围内(继承别的类,实现接口)

2. 方法名相同(废话!)

3. 形参组成相同(类型、个数均相同)

4. 返回类型相同

个人理解:

1. 既然是覆盖,要完全盖住,学的像点,所以方法的外表要看上去一样嘛。

2. 实现接口方法,也可称为覆盖,毕竟是把空的方法体覆盖为具体的代码了。想想也是,实现接口的时候IDE是不是为我们自动加上了@Override注解?这个在JDK6之前的版本可不行,写这个注解是会报错的。(怀念起在老东家运维JDK1.5项目的时光)

Java重载、重写、覆盖、隐藏的总结_第1张图片

要注意的地方:派生方法不能抛出比基类方法范围更广的异常(速记:孩子不能闯比父母更大的祸),

                         错误范例:基类方法throws IOException,派生方法却throws Exception。

                         派生方法不能有比基类方法更大的访问度(速记:孩子不能比父母更能显摆),

                         错误范例:基类方法是protected,派生方法却是public。

隐藏Hiding

发生要素如下:

1. 同覆盖的1.2.3.4条件(必要)

2. 仅发生在静态方法上

要点:

隐藏不需要@Override注解修饰,加上会报错。且派生方法的可抛出异常范围和可访问范围的约束与覆盖相同(不能抛更多异常,不能有更广的访问权限)。

在jls11文档中,隐藏注明为 by Class Methods,而覆盖则是by Instance Methods,这个很好理解,静态的成员方法就是属于这个类的,隐藏也可以叫类的方法的覆盖。

个人理解:静态方法是和类绑定到一起的,那么在实例化的时候,用的谁的类型的引用,那么call到的方法就是谁的实现,也许说的不恰当,请看下例:

       class Super {
           static String greeting() { return "Goodnight"; }
           String name() { return "Richard"; }
       }
       class Sub extends Super {
           static String greeting() { return "Hello"; }
           String name() { return "Kick"; }
       }
       class Test {
           public static void main(String[] args) {
               Super s = new Sub();  
               System.out.println(s.greeting() + ", " + s.name());
               //输出:Goodnight, Kick
               Sub s2 = new Sub();
               System.out.println(s2.greeting() + ", " + s.name());
               //输出:Hello, Kick
           } 

}

由于s的类型是Super,所以greeting()执行的是Super的实现,但是name()是正常的覆盖,好比派生类没有重写greeting()一样(派生类干的事儿被藏起来了)。但是s2 call到的就是Sub的实现了,符合常规的思路。

 

  本文参考:jsl11文档

你可能感兴趣的:(Java)