• Java 重载、重写和隐藏的区别


    Java 重载、重写和隐藏的区别

     

     

    一、重载(Overload)

    注意:为了正确的区分重载和重写,请各位务必记清重载(Overload)和重写(Override)的英文。

    1)重载定义:表示两个或多个方法的名字相同,但方法的参数不同。方法参数不同有两层含义:A、参数的个数不同;B、参数的类型不同。

    [java] view plain copy

    1. public void run(String name, int count)  
    2. {  
    3. System.out.println(count + " " + name + " " + "are running.");  
    4. }  
    5. public void run(int count, String name)  
    6. {  
    7. System.out.println(count + " " + name + " " + "are running.");  
    8. }  

    请思考以上两个方法是否构成了重载?

    2)重载发生的时机:重载是发生在同一个类内部的两个或多个方法之间。

    3)方法的返回类型对重载没有任何影响!即,对于方法名字和参数都相同的两个方法,如果他们的返回类型不同,这种语法格式是错误的,大家可以试一试。那么,也就是说,只要是重载返回类型一定相同。否则为两个不同的方法。如下代码,这是两个不同的方法。

    [java] view plain copy

    1. public void run()  
    2. {  
    3. System.out.println("dog is running");  
    4. }  
    5. public int run(String name, int count)  
    6. {  
    7. System.out.println(count + " " + name + " " + "are running.");  
    8. return 1;  
    9. }  

    3)构造方法之间的重载:一个类中有多个构造方法,那么它们一定是重载的。

    4)重载方法之间的调用:对于普通方法的重载,重载的方法之间是可以直接调用的,如下代码一。

    但是对于重载的构造方法之间的调用,需要使用this()关键字。A、this()括号中参数表示目标构造方法所接收的参数;B、对this()的调用必须是构造方法的第一条语句。如下代码二。

    [java] view plain copy

    1. public int run(String name, int count)  
    2. {  
    3. System.out.println(count + " " + name + " " + "are running.");  
    4. return 1;  
    5. }  
    6. public void run(int count, String name)  
    7. {  
    8. run(name , count);  
    9. System.out.println(count + " " + name + " " + "are running.");  
    10. }  

    [java] view plain copy

    1. public Dog()  
    2. {  
    3. this("金巴");  
    4. System.out.println("你好世界,我是一条狗!");  
    5. }  
    6. public Dog(String name)  
    7. {  
    8. System.out.println("你好世界," + "我是一条" + name + "狗!");  
    9. }  

    二、重写(Override)

    1)重写定义:子类与父类的方法的返回类型一样,方法名称一样,参数一样,这样我们就说子类与父类的方法构成了重写关系。

     补充:在重写中,我们一直没提到权限的问题(public、protected、private),使用private修饰的方法是不能够进行重写的,也不能够被继承,所以private和多态扯不上关系。在同一个包下,构成重写关系,父类和子类的方法,权限可以是public和public、protected和protected、protected和public,但不可能是public和protected,即权限可以扩大但不可缩小。

    2)重写发生的时机:重写发生在父类与子类之间。

    3)构造方法时不能重写的,如果您理解是构造方法的作用,就知道构造方法为什么不能重写。

    4)在重写时,子类重写的方法调用父类被重写的方法时,可以使用super.父类方法的方式调用,其中此语句不必放在第一行。如下代码所示:

    [java] view plain copy

    [java] view plain copy

    1. class Animal  
    2. {  
    3. public void run()  
    4. {  
    5. System.out.println("animal is running");  
    6. }  
    7. }  
    8. class Dog extends Animal  
    9. {  
    10. //override  
    11. public void run()  
    12. {  
    13. System.out.println("dog is running");  
    14. super.run();  
    15. }  
    16. }  

    三、隐藏(Hide)
    1)提到隐藏,就不得不提到一个关键字--static,static是静态的意思,具体用法意义,各位可以去查相关的资料。这里我想说的,static方法在继承中的特殊性!
    1)子类不能重写(Overriding)父类的静态方法,只能隐藏(Hiding)父类的静态方法。

    2)什么叫隐藏父类的静态方法呢?就是说父类的静态方法和子类的静态方法是同时存在的,具体调用的是哪个方法,是要看调用的方法的引用是什么类型的引用,如果是父类型的引用,调用的就是父类的静态方法,如果是子类型的引用,调用的就是子类的静态方法。【这里面有些多态(Polymorphism)的知识,不懂的可以问我哈!】具体区别我们可以看一个例子,这个例子来自官方文档。

    [java] view plain copy

    1. public class Animal   
    2. {  
    3. public static void testClassMethod()   
    4. {  
    5. System.out.println("The class" + " method in Animal.");  
    6. }  
    7. public void testInstanceMethod()   
    8. {  
    9. System.out.println("The instance " + " method in Animal.");  
    10. }  
    11. }  

    The second class, a subclass of Animal, is called Cat:

    [java] view plain copy

    1. public class Cat extends Animal   
    2. {  
    3. public static void testClassMethod()   
    4. {  
    5. System.out.println("The class method" + " in Cat.");  
    6. }  
    7. public void testInstanceMethod()  
    8. {  
    9. System.out.println("The instance method" + " in Cat.");  
    10. }  
    11. public static void main(String[] args)   
    12. {  
    13. Cat myCat = new Cat();  
    14. Animal myAnimal = myCat;  
    15. Animal.testClassMethod();  
    16. myAnimal.testInstanceMethod();  
    17. }  
    18. }  

     

     

    隐藏:父类和子类拥有相同名字的属性或者方法时,父类的同名的属性或者方法形式上不见了,实际是还是存在的。

     

    隐藏现象发生在子类和父类之间,隐藏是针对父类中成员变量和静态方法而言。

    当子类声明与父类中成员变量具有相同的变量名的变量时,则实现了对父类中成员变量的隐藏;

    当子类声明了与父类中的静态成员方法具有相同的方法名,参数列表和相同的返回值时,则实现了对父类中静态方法的隐藏。

      注意:当发生隐藏的时候,声明类型是什么类,就调用对应类的属性或者方法,而不会发生动态绑定

          方法隐藏只有一种形式,就是父类和子类存在相同的静态方法

          属性只能被隐藏,不能被覆盖

          子类实例变量/静态变量可以隐藏父类的实例/静态变量,总结为变量可以交叉隐藏

    隐藏和覆盖的区别:

      被隐藏的属性,在子类被强制转换成父类后,访问的是父类中的属性

      被覆盖的方法,在子类被强制转换成父类后,调用的还是子类自身的方法

      因为覆盖是动态绑定,是受RTTI(run time type identification,运行时类型检查)约束的,隐藏不受RTTI约束,总结为RTTI只针对覆盖,不针对隐藏

     

    特殊情况:

      1.final修饰的属性可以被隐藏,但是不能被赋值,即不能用=来赋值,网上说final属性不能被修改,这个说法不准确,因为对于引用类型的变量用final修饰后,它只是不能被指向其他对象,但是可以改它自身的值,可以用ArrayList测试,final属性可以在运行的时候进行初始化,但是不能不出现初始化语句

      2.final修饰的方法不能被覆盖,可以被重载

      3.final修饰的类不能被继承

      4.private 方法隐式添加了final

    实例:

    SuperClass类:

       package com.yilong.test.scjp;  

    1. public class SuperClass {  
    2. public static int i = 1;  
    3. public int j = 2;  
    4. public final int k = 3;  
    5. public static void method1() {  
    6. System.out.println("SuperClass Method1");  
    7. }  
    8. public void method2() {  
    9. System.out.println("SuperClass Method2");  
    10. }  
    11. public final void method3() {  
    12. System.out.println("SuperClass Method3");  
    13. }  
    14. }  
  • 相关阅读:
    2011/6/24 数据库分析
    项目代码总结
    背景透明 by sofish
    ie6 reflow bug
    ID与CLASS的使用技巧
    CSS浮动属性Float详解 by 帕兰
    javascript闭包 by 李松峰
    详解CSS选择器、优先级与匹配原理
    垂直对齐:verticalalign属性 by ddcatlee
    行高lineheight,以及基线、顶线、中线和底线,还有内容区域、行内框和行框 by 豆豆猫的窝
  • 原文地址:https://www.cnblogs.com/weichunguang/p/7646933.html
Copyright © 2020-2023  润新知