zoukankan      html  css  js  c++  java
  • Java类成员(成员变量和方法)的覆盖与隐藏归纳

     Java类成员(成员变量和方法)的覆盖与隐藏归纳

    以前就知道重写override和重载overload的区别,平时也是逮着用就是了,Eclipse报错再说。

    最近看一本书里面出现了重写、替换、覆盖、置换、隐藏、重载,简直乱得不行,归纳整理一下。

    从全局来看,java只有重写、隐藏、重载3种,具体归纳如下:

    基本概念:

    方法签名:方法名+参数列表(参数类型、个数、顺序)。
    =================================【重写】=================================

    某些书又叫覆盖、替换、置换。本文统一叫重写。

    只有实例方法可以被重写!重写后的方法必须仍为实例方法!(实例方法------重写------>实例方法)
    成员变量和静态方法都不能被重写,只能被隐藏。

    重写实例方法:超类Parent中有实例方法A,子类child定义了与A“相同签名和子集返回类型”的实例方法B,子类对象ChildObj只能调用自己的实例方法B。
                                  即使将子类对象ChildObj转换为超类对象ParentObj,ParentObj依然只能调用重写后的实例方法B!
                                  (超类对象ParentObj中的实例方法A已经被实例方法B覆盖了)

           

    重写的语法规则如下:
    (1)方法签名必须相同(参数类型、个数、顺序);
    (2)对返回类型有要求,分2种情况:
         a.被重写方法的返回类型是基本类型:重写方法的返回类型必须“相同”。
                    基本类型包括了(byte,short,int,long,float,double,char,boolean,其实还包括一个void类型),但要注意返回类型是封装类时属于下面的情况b。
         b.被重写方法的返回类型是引用类型:重写方法的返回类型应“相同”或是其“子类型”;
                    引用类型包括了数组、string等一切非基本类型的类型(即类类型)。
    (3)重写方法的访问权限不能小于被重写方法的访问权限,可以更广泛。如被重写方法是包访问权限,重写方法是public访问权限。
         重写方法可以改变其它的方法修饰符,如final、synchronized、native、strictfp。
         不管被重写方法中有无final修饰的参数,重写方法都可以增加、保留、去掉这个参数的final修饰符(参数修饰符不属于方法签名)。
    (4)重写方法抛出的异常范围不能大于被重写方法抛出的异常的范围(也可以不抛出异常)。
    (5)不能重写final方法。(final修饰符存在的意义就是防止任何子类重写该方法)
    (6)不能重写static静态方法。(形式上可以写,但本质上不是重写,属于下面要讲的隐藏)
    (7)如果一个方法不能被继承,则不能重写它。或者说:只有当方法可以被访问时才可以被重写。
         典型的就是超类的private方法。

    对于(3)需要注意:
    1.重写override对返回类型有要求,而重载overload对返回类型没有要求。
       重载可以改变返回类型。因为编译器通过对方法签名的识别即可静态编译出不同的方法。这也是java中重载与重写的区别之一。
    2.严格来说,重写属于多态,因为是动态绑定(或称为动态联编),而重载是静态绑定,编译时即可确定。

    =================================【隐藏】=================================

    隐藏与覆盖在形式上极其类似(语法规则),但有着本质的区别。

    只有成员变量(不管是不是静态)和静态方法可以被隐藏。

    ----------------------------成员变量------------------------

    隐藏成员变量:超类Parent中有成员变量A,子类Child定义了与A同名的成员变量B,子类对象ChildObj调用的是自己的成员变量B。
                                  如果把子类对象ChildObj转换为超类对象ParentObj,ParentObj调用的是超类的成员变量A!
                                  注:1.隐藏成员变量时,只要同名即可,可以更改变量类型(无论基本类型还是隐藏类型)
                                           2.不能隐藏超类中的private成员变量,换句话说,只能隐藏可以访问的成员变量。
                                           3.隐藏超类成员变量A时,可以降低或提高子类成员变量B的访问权限,只要A不是private
                                           4.隐藏成员变量与是否静态无关!静态变量可以隐藏实例变量,实例变量也可以隐藏静态变量
                                           5.可以隐藏超类中的final成员变量。

     

    ----------------------------静态方法------------------------

    隐藏后的方法必须仍为静态方法!(静态方法------隐藏------>静态方法)

    隐藏静态方法:超类Parent有静态方法A,子类Child定义了与A“相同签名和子集返回类型”的静态方法B,子类对象ChildObj调用的是自己的静态方法B。
                                  如果把子类对象ChildObj转换为超类对象ParentObj,ParentObj调用的是超类的静态方法A!

    隐藏超类静态方法的语法规则与重写实例方法的规则几乎完全相同,只需要修改第(6)条为:(6)不能隐藏实例方法。。

    示例代码:

    [java] view plaincopy
     
    1. class Animal {  
    2.     char hairColor='B';  
    3.     int legNumber=2;  
    4.     static boolean isHuman=true;  
    5.     public static void testClassMethod() {  
    6.         System.out.println("The class" + " method in Animal.");  
    7.     }  
    8.   
    9.     public void testInstanceMethod() {  
    10.         System.out.println("The instance " + " method in Animal.");  
    11.     }  
    12. }  
    13.   
    14. public class Cat extends Animal {  
    15.     static int hairColor=1;  
    16.     char legNumber='A';  
    17.     double isHuman=3.1415926E5;   
    18.     public static void testClassMethod() {  
    19.         System.out.println("The class method" + " in Cat.");  
    20.     }  
    21.   
    22.     public void testInstanceMethod() {  
    23.         System.out.println("The instance method" + " in Cat.");  
    24.     }  
    25.   
    26.     public static void main(String[] args) {  
    27.         System.out.println("========child class=========");  
    28.         Cat myCat = new Cat();  
    29.         System.out.println("myCat.hairColor="+myCat.hairColor);  
    30.         System.out.println("myCat.legNumber="+myCat.legNumber);  
    31.         System.out.println("myCat.isHuman="+myCat.isHuman);  
    32.         myCat.testClassMethod();  
    33.         myCat.testInstanceMethod();  
    34.         System.out.println("========child class ---> parent class=========");  
    35.         Animal myAnimal = myCat;  
    36.         System.out.println("========parent class=========");  
    37.         System.out.println("myAnimal.hairColor="+myAnimal.hairColor);  
    38.         System.out.println("myAnimal.legNumber="+myAnimal.legNumber);  
    39.         System.out.println("myAnimal.isHuman="+myAnimal.isHuman);         
    40.         myAnimal.testClassMethod();  
    41.         myAnimal.testInstanceMethod();  
    42.     }  
    43. }  
    输出结果:
    [java] view plaincopy
     
    1. ========child class=========  
    2. myCat.hairColor=1  
    3. myCat.legNumber=A  
    4. myCat.isHuman=314159.26  
    5. The class method in Cat.  
    6. The instance method in Cat.  
    7. ========child class ---> parent class=========  
    8. ========parent class=========  
    9. myAnimal.hairColor=B  
    10. myAnimal.legNumber=2  
    11. myAnimal.isHuman=true  
    12. The class method in Animal.  
    13. The instance method in Cat.  
  • 相关阅读:
    Google
    LeetCode 664. 奇怪的打印机
    LeetCode 79. 单词搜索
    LeetCode 224. 基本计算器
    Windows 端口映射
    LeetCode 354. 俄罗斯套娃信封问题
    LeetCode 300. 最长递增子序列
    LeetCode 338. 比特位计数
    LeetCode 395. 至少有K个重复的最长子串
    LeetCode 424. 替换后的最长重复字符
  • 原文地址:https://www.cnblogs.com/lubocsu/p/5117421.html
Copyright © 2011-2022 走看看