zoukankan      html  css  js  c++  java
  • java的super和this关键字用法总结

     

    ------super关键字------

            
            super用途:在子类中访问超类“被隐藏的成员变量(无论是否静态)和静态方法”以及“被重写的实例方法”。这里的超类必须是“直接超类”,即子类之上最近的超类。
            super的用法:
            ①在子类构造方法中调用超类的构造方法,用“super(ParamList)”的方式调用,ParamList根据超类构造方法而定,可以为空。另外super(ParamList)必须是子类构造方法的第一句。
            ②当超类的成员变量因与子类的成员变量同名而被隐藏时(成员变量隐藏与是否静态无关),可用"super.memberVariableName"来访问超类的成员变量。
                注意:有些人说当超类的成员变量与子类某方法的局部变量或参数同名时,也属于被隐藏。那么一旦离开该方法隐藏还成立吗,显然这种说法是错误的。隐藏概念只限于成员变量范围,方法体内的局部变量与成员变量同名属于下面的this要讨论的内容。
                             假设有超类parent,其中有成员变量A,子类child,其中有方法method(type A)存在:
                            1)如果子类没有隐藏超类成员变量A,在method(type A)中,无论使用this.A还是super.A都是一样的,都会访问超类成   员变量A;(this.A就是继承下来的,换句话说,对于自然继承下来(没有隐藏/重写)的成员变量甚至是方法,super.memberName=this.membername)
                            2)如果子类有成员变量A隐藏了超类成员变量A,在method(type A)中,super.A=parent.A,this.A=child.A,两者有区别。
            ③当超类的静态方法/实例方法被子类隐藏/重写时,可使用"super.methodName(ParamList)"来访问超类方法。对于静态方法而言,这没什么奇怪,对于实例方法而言,这种用法使得超类被重写的方法在子类中可见。

    最后需要注意,super关键字不能在静态方法中使用!
    ------this关键字------
            
             this的用途:引用对象本身。
    当一个对象创建后,Java虚拟机就会给这个对象分配一个引用自身的指针,这个指针的名字就是this。因此,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this。并且this只和特定的对象关联,而不和类关联,同一个类的不同对象有不同的this。
             this用法:
             ①在构造方法中,用this(ParamList)调用自己的另一个构造方法,this(ParamList)必须放在第一句位置!此用法只限于在构造方法中使用。
             ②某方法的参数或局部变量与某个成员变量同名时,在该方法中要访问该成员变量需要用“this.memberVariableName”的形式。
             ③某方法中需要引用其所属类的当前对象时,直接用this来引用当前对象。
    示例代码:
    [java] view plaincopy
     
    1. import java.lang.reflect.Field;  
    2. import java.lang.reflect.Modifier;  
    3.   
    4. class A {  
    5.     int x;  
    6.     static double y;  
    7.     char z;  
    8.   
    9.     A(char z) {  
    10.         this.z = z; // this访问成员变量,以区分同名参数  
    11.     }  
    12.   
    13.     A(double newy, char newz) {  
    14.         double y = newy; // this访问成员变量,以区分同名局部变量  
    15.         char z = newz;  
    16.         this.y = y; // 因y是静态成员变量,最好使用className.staticMemberVarName即A.y访问  
    17.         this.z = z;  
    18.     }  
    19.   
    20.     A(int a, double b, char c) {  
    21.         this(b, c);// 使用this(paramList)调用另一个构造方法必须放在第一句位置  
    22.         this.x = a;// 此处无法再使用this(x);理由同上  
    23.     }  
    24.   
    25.     void OutPut() {  
    26.         if (this.equals(this))// this作为对象引用使用,当然此条件永远=true  
    27.             System.out.println("我是类" + GetClassName() + "的方法"  
    28.                     + GetInvokeMethodName());  
    29.     }  
    30.   
    31.     String GetClassName() {  
    32.         return this.getClass().getName();  
    33.     }  
    34.   
    35.     String GetInvokeMethodName() {  
    36.         String TempName = new Exception().getStackTrace()[1].getMethodName();  
    37.         return TempName;  
    38.     }  
    39.   
    40.     static void showStaticFieldValue(Object obj) throws Exception { //  
    41.         Field fields[] = obj.getClass().getDeclaredFields();  
    42.         String fieldName, fieldModifier, fieldType;  
    43.         Object val;  
    44.         for (int i = 0; i < fields.length; i++) {  
    45.             Field field = fields[i];  
    46.             if (field.toString().indexOf("static") != -1) {  
    47.                 // System.out.println(field.toString());  
    48.                 fieldName = field.getName();  
    49.                 fieldType = field.getType().getName();  
    50.                 fieldModifier = Modifier.toString(field.getModifiers());  
    51.                 field.setAccessible(true);  
    52.                 val = field.get(obj);  
    53.                 System.out.println(fieldModifier + " " + fieldType + " "  
    54.                         + fieldName + " = " + val);  
    55.             }  
    56.         }  
    57.     }  
    58.   
    59.     void getStaticFieldValue() {  
    60.         try {  
    61.             showStaticFieldValue(this);  
    62.         } catch (Exception e) {  
    63.   
    64.         }  
    65.     }  
    66. }  
    67.   
    68. class B extends A {  
    69.     static double x;// 隐藏超类A的成员变量x  
    70.     int y = (int) this.x + 1;// 隐藏超类A的成员变量y,有人说this必须在方法体中使用,无情的击破其谣言。  
    71.   
    72.     // 继承了超类A的成员变量z,仍为char z;  
    73.   
    74.     B(char c) {  
    75.         super(c);/* 
    76.                  * super(c)调用超类构造函数的目的在于初始化自然继承的超类成员,若子类完全隐藏了超类的成员变量, 则可以不用super 
    77.                  * super(ParamList)访问超类构造函数 疑问: 1.类B隐藏且改变了类A的成员变量, 
    78.                  * super(b)是否仅仅改变了B中包含的A对象的值, 而B中的static double x的值仍然为默认值?(待验证) 
    79.                  * 2.java的构造方法属于实例方法还是静态方法? 
    80.                  */  
    81.         x = super.y + 1.0;// super访问超类被隐藏的成员变量double y,也可以写成A.y  
    82.         y = super.x;// super访问超类被隐藏的成员变量int x  
    83.     }  
    84.   
    85.     String GetClassName() {// 重写超类A的GetClassName()  
    86.         return "类类类BBB";  
    87.     }  
    88.   
    89.     String GetInvokeMethodName() {// 重写超类A的GetInvokeMethodName()  
    90.         return "方法名称方法名称方法名称";  
    91.     }  
    92.   
    93.     void OutPut() { // 重写超类的OutPut实例方法.  
    94.         System.out.println("super调用超类被重写的两个方法输出:类名="  
    95.                 + super.GetClassName() + ",方法名=" + super.GetInvokeMethodName());// super调用超类的实例方法  
    96.         System.out.println("用类B的重写方法输出:类名=:" + GetClassName() + ","  
    97.                 + ",方法名="+GetInvokeMethodName());// 调用自己的方法  
    98.     }  
    99.   
    100.     static void showStaticFieldValue(Object obj) throws Exception { // 隐藏超类的静态方法  
    101.         System.out.println("static Field doulbe x=" + x);  
    102.     }  
    103.   
    104.     void getStaticFieldValue() {  
    105.         try {  
    106.             System.out.println("super调用超类A的方法输出静态成员变量");  
    107.             super.showStaticFieldValue(this); // super调用超类被隐藏的静态方法  
    108.             System.out.println("类B自己的方法输出静态成员变量");  
    109.             showStaticFieldValue(this);// 类B自己的方法  
    110.         } catch (Exception e) {  
    111.         }  
    112.     }  
    113. }  
    114.   
    115. class Example3_15 {  
    116.     public static void main(String[] args) {  
    117.         A myA = new A(8, 6.0, 'k');  
    118.         B myB = new B('哦');  
    119.         myA.getStaticFieldValue();  
    120.         myA.OutPut();  
    121.         System.out.println("====================");  
    122.         myB.getStaticFieldValue();  
    123.         myB.OutPut();  
    124.     }  
    125. }   
  • 相关阅读:
    Ubuntu 14.04 卸载通过源码安装的库
    Ubuntu 14.04 indigo 相关依赖
    Ubuntu 14.04 indigo 安装 cartographer 1.0.0
    Ubuntu 14.04 改变文件或者文件夹的拥有者
    安装cartographer遇到Unrecognized syntax identifier "proto3". This parser only recognizes "proto2"问题
    Unrecognized syntax identifier "proto3". This parser only recognizes "proto2". ”问题解决方法
    查看所有用户组,用户名
    1卸载ROS
    Ubuntu14.04 软件安装卸载
    Ubuntu14.04系统显示器不自动休眠修改
  • 原文地址:https://www.cnblogs.com/lubocsu/p/5117426.html
Copyright © 2011-2022 走看看