动态

详情 返回 返回

【Java】this、super關鍵字,代碼塊介紹 - 动态 详情

文章目錄

一. this引用

1. this引用的介紹

  • this引用是成員方法的參數之一,不需要用户傳遞實現,由編譯器自動完成,也就是説,這個參數用户是看不到的,但用户可使用這個參數。
  • this引用指向當前對象(成員方法運行時調用該成員方法的對象),在成員方法中所有成員變量的操作,都是通過該引用去訪問。 只不過所有的操作對用户是透明的,即用户不需要來傳遞,編譯器自動完成。
  • this 引用的是調用成員方法的對象。

2. this引用的特性

  1. this的類型:對應類 類型引用,即哪個對象調用就是哪個對象的引用類型
  2. this只能在"成員方法"中使用
  3. 在"成員方法"中,this只能引用當前對象,不能再引用其他對象
  4. this是“成員方法”第一個隱藏的參數,編譯器會自動傳遞,在成員方法執行時, 編譯器會負責將調用成員方法對象的引用傳遞給該成員方法,this負責來接收

  1. 用户也可以將由編譯器實現的形參this手動給出,但實參中不能有其對應的對象的引用,否則會報錯

3. this引用所解決的問題

看下面給出的代碼, 當方法形參名與成員變量名相同 ;但我們沒有手動通過this引用去調用成員變量;

看執行結果可以發現此時並沒有完成對於成員變量的賦值,因為在方法中遵循局部變量優先的原則,就不會去訪問成員變量,只是形參自己給自己賦值而已

public class Date { 
    public int year;
    public int month;
    public int day;

    public  void  setDay(int year,  int month,  int day){ 
        year = year;
        month = month;
        day = day;
    }

    public  void  printDate(){ 
        System.out.println(year + "/" + month + "/" + day);
    }

    public  static  void  main(String[] args)  { 

       // 構造三個日期類型的對象 d1 d2 d3
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();
        // 對d1,d2,d3的日期設置
        d1.setDay(2022,8,15);
        d2.setDay(2022,8,16);
        d3.setDay(2022,8,17);
        // 打印日期中的內容
        d1.printDate();
        d2.printDate();
        d3.printDate();
    }
}

執行結果:

要解決這裏的問題只需要通過this去訪問成員變量即可,此時就可以區分形參和成員變量了

public void setDay(int year, int month, int day){ 
        this.year = year;
        this.month = month;
        this.day = day;
}

執行結果:

4. this的三種用法

  • this.成員變量
  • this.成員方法
  • this( );訪問構造方法(在構造方法博客中介紹)

二. super關鍵字

1. super關鍵字的介紹

由於設計不好,或者因場景需要,子類和父類中可能會存在相同名稱的成員,如果要在子類方法中訪問父類同名成 員時,該如何操作?

直接訪問是無法做到的,因為局部優先的的原則,會直接訪問子類的成員。

Java提供了 super關鍵字,該關鍵字主要作用:在子類方法中訪問父類的成員。

【注意事項】

  1. super只能在非靜態方法中使用
  2. super可以用來在子類方法中,訪問父類的成員變量和方法。

    public class  Base  { 
    int a;
    int b;
    public  void  methodA(){ 
        System.out.println("Base中的methodA()");
    }
    public  void  methodB(){ 
        System.out.println("Base中的methodB()");
    }
    }
    
    class  Derived  extends  Base{ 
    int a; // 與父類中成員變量同名且類型相同
    char b; // 與父類中成員變量同名但類型不同
    // 與父類中methodA()構成重載
    public  void  methodA(int a)  { 
        System.out.println("Derived中的method()方法");
    }
    // 與基類中methodB()構成重寫
    public  void  methodB(){ 
        System.out.println("Derived中的methodB()方法");
    }
    public  void  methodC(){ 
    // 對於同名的成員變量,直接訪問時,訪問的都是子類的
        a = 100; // 等價於: this.a = 100;
        b = 101; // 等價於: this.b = 101;
    // 注意:this是當前對象的引用
    // 訪問父類的成員變量時,需要藉助super關鍵字
    // super是獲取到子類對象中從基類繼承下來的部分
        super.a = 200;
        super.b = 201;
    // 父類和子類中構成重載的方法,直接可以通過參數列表區分清訪問父類還是子類方法
        methodA(); // 沒有傳參,訪問父類中的methodA()
        methodA(20); // 傳遞int參數,訪問子類中的methodA(int)
    // 如果在子類中要訪問重寫的基類方法,則需要藉助super關鍵字
        methodB(); // 直接訪問,則永遠訪問到的都是子類中的methodA(),基類的無法訪問到
        super.methodB(); //訪問基類的methodB()
    }
    }

    2. super的三種用法

  • super.子類中從父類繼承的成員變量
  • super.子類中從父類繼承的成員方法
  • super( );調用父類的構造方法(在構造方法博客中介紹)

三. super和this的比較

1. 相同點

  1. 都是Java中的關鍵字
  2. 只能在類的非靜態方法中使用,用來訪問非靜態成員方法和字段
  3. 在構造方法中調用時,必須是構造方法中的第一條語句,並且不能同時存在

2. 不同點

  1. this是當前對象的引用,當前對象即調用實例方法的對象,super相當於是子類對象中從父類繼承下來部分成員的引用(注意不是父類的引用,子類繼承父類並沒有創建父類對象)
  2. 在非靜態成員方法中,this用來訪問本類的方法和屬性,子類對象中如果沒有重名現象的發生,this也可以訪問到父類繼承下來的方法和屬性;但super只能用來用來訪問父類繼承下來的方法和屬性

  1. 在構造方法中:this(…)用於調用本類構造方法,super(…)用於調用父類構造方法,兩種調用不能同時在構造方法中出現
  2. 子類構造方法中一定會存在super(…)的調用 ,用户沒有寫編譯器也會自動給出;但是要在子類構造方法中調用子類其他構造方法,需要用户手動添加this(…)

四. 代碼塊概念以及分類

使用 { } 定義的一段代碼稱為代碼塊。

根據代碼塊定義的位置以及關鍵字,又可分為以下四種:

  • 普通代碼塊
  • 構造代碼塊
  • 靜態代碼塊
  • 同步代碼塊

1. 普通代碼塊

普通代碼塊:定義在方法中的代碼塊, 其內的變量只在代碼塊中有效,這種用法較少見。

public class Main{ 
    public  static  void  main(String[] args)  { 

        {
  //直接使用{ }定義,普通方法塊
            int x = 10 ;
            System.out.println("x1 = " +x);
        }

        int x = 100 ;
        System.out.println("x2 = " +x);
    }
}

2. 構造代碼塊

定義在類中的代碼塊(不加修飾符)。

也叫: 實例代碼塊 。構造代碼塊一般用於初始化實例成員變量。

public class Student{ 
    //實例成員變量
    private String name;
    private String gender;
    private int age;

    //實例代碼塊
    { 
        this.name = "xinxin";
        this.age = 21;
        this.gander = "nan";
        System.out.println("I am instance init()!");
    }

    public  void  show(){ 
        System.out.println("name: "+name+" age: "+age+" gender: "+gender);
    }
}

public class Main { 
    public  static  void  main(String[] args)  { 
        Student stu = new Student();
        stu.show();
    }
}

3. 靜態代碼塊

使用static定義的代碼塊稱為靜態代碼塊。一般用於初始化靜態成員變量。

public class Student{ 
    private String name;
    private int age;
    private static String classRoom;

    //實例代碼塊
    { 
        this.name = "xin";
        this.age = 21;
        System.out.println("I am instance init()!");
    }

    // 靜態代碼塊
    static { 
        classRoom = "rj2104";
        System.out.println("I am static init()!");
    }

    public  static  void  main(String[] args)  { 
        Student s1 = new Student();
        Student s2 = new Student();
    }
}

4. 注意事項

  • 靜態代碼塊不管生成多少個對象,其只會執行一次
  • 靜態成員變量是類的屬性,因此是在JVM加載類時開闢空間並初始化的
  • 如果一個類中包含多個靜態代碼塊,在編譯代碼時,編譯器會按照定義的先後次序依次執行(合併)
  • 實例代碼塊只有在創建對象時才會執行

Add a new 评论

Some HTML is okay.