java學習(九)static和this使用

java學習(九)static和this使用

static:翻譯爲靜態

  • 所有static關鍵詞修飾的都是類相關的,不需要new對象,都是採用類名.的形式訪問,不會出現空指針異常

  • static修飾的方法稱爲靜態方法,static修飾的變量稱爲靜態變量

複習變量(引出靜態變量)

  • 方法體內聲明的變量叫局部變量

  • 方法體外聲明的變量叫成員變量

    • 成員變量可以分爲靜態變量和實例變量,在實例變量前加static關鍵詞就是靜態變量了

靜態代碼塊

  • 靜態代碼塊在類加載時執行,並且只執行一次。 靜態代碼塊實際上是 java 語言爲程序員準備的一個特殊的時刻,這個時刻就 是類加載時刻。

靜態代碼塊:

public class StaticTest01{
​
    //靜態代碼塊
    static{
        System.out.println(111);  //先執行
    }
​
    public static void main(String[] args) 
    {
        System.out.println("main 執行!");  //最後執行
    }
​
    //靜態代碼塊
    static{
        System.out.println(222);  //然後執行
    }
}
//靜態代碼塊先執行,然後纔是方法執行
  • 可以得知:靜態代碼塊是在main方法之前執行的,是因爲靜態代碼塊在類加載時執行,並且只執行一次。

訪問靜態變量和實例變量

public class StaticTest02{
    
    //實例變量
    int i = 100;
​
    //靜態變量
    static int j = 111;
    
    static{
    
        System.out.println(i);  //java:11: 錯誤: 無法從靜態上下文中引用非靜態 變量 i
​
        System.out.println(j);  //編譯成功
    }
​
    public static void main(String[] args){
        System.out.println("Hello World!");
    }
}

靜態屬性

  • 當一個類的某個屬性值不會隨着對象的改變而變化的時候,建議將該屬性定義爲靜態屬性。

  • 靜態變量在類加載的時候初始化,存儲在方法區當中,不需要創建對象,直接通過類名訪問

靜態方法

  • 在實際的開發中,“工具類”當中的方法一般定義爲靜態方法,因爲工具類就是爲 了方便大家的使用,將方法定義爲靜態方法,比較方便調用,不需要創建對象,直接使用類名 就可以訪問。

  • 當某個動作 在觸發的時候需要對象的參與,這個方法應該定義爲實例方法

java中的this是什麼,內存中存儲在哪裏,要掌握 this 在實例方法和構造方法中的 用法。

  • this 可以看做一個變量,它是一個“引用”,存儲在 Java 虛擬機堆內存的對象內部,this 這個“引用”保存了當前對象的內存地址指向自身,任何一個堆內存的 java 對象都有一個 this 。

  • this 指向“當前對象”,也可以說 this 代表“當前對象”,this 可以使用在實例方法中以及 構造方法中,語法格式分別爲“this.”和“this(..)”。this 不能出現在帶有 static 的方法當中。

public class ThisInStaticMethod{
​
    public static void main(String[] args) {
​
        ThisInStaticMethod.method();
    }
    public static void method(){
​
        System.out.println("method執行");
        System.out.println(this);  //java:11: 錯誤: 無法從靜態上下文中引用非靜態 變量 this
​
    }
}
​

得知:this不能出現在 static的方法當中,static 方法執行的過程中是不需要“當前對象”參與的,所以 static 的方法中不能使用 this,因爲 this 代表的 就是“當前對象”。

this:this只能在實例方法中使用,誰調用這個實例方法,this就是誰,this是當前對象和python的self差不多

public class Customer{
​
    private String name;
​
    //無參構造方法
    public Customer(){
    }
​
    //有參構造方法
    public Customer(String _name){
        name = _name;
    }
    
    //set
    public void setName(String _name){
        name = _name;
    }
​
    //get
    public String getName(){
        return name;
    }
​
    //定義一個方法
    public void shopping(){
    
        System.out.println(name + "is shopping!");  //誰調用就打印誰
    }
}
​

調用

public class Customer{
​
    private String name;
​
    //無參構造方法
    public Customer(){
    }
​
    //有參構造方法
    public Customer(String _name){
        name = _name;  //這裏的name就是實例變量neme,_name是接收的局部變量
    }
    
    //set
    public void setName(String _name){
        name = _name;
    }
​
    //get
    public String getName(){
        return name;
    }
​
    //定義一個實例方法
    public void shopping(){
        System.out.println(this.name + "is shopping!");  //誰調用就打印誰
        System.out.println(name + "is shopping!");  //誰調用就打印誰
    }
}

得 知 :在實例方法中可以 直接訪問當前對象的實例變量,而“this.”是可以省略的。

那麼this在什麼時候不能省略?

當接收的局部變量參數和實例變量相同的時候,例:name = name;需要寫成this.name = name這裏的this就不可以省略了哈哈哈哈。【否則name = name這兩個name都會被識別成局部變量哦】

上面Customer代碼塊修改:

    //定義一個實例方法
    public void shopping(){
    
        System.out.println(name + "is shopping!");  //誰調用就打印誰
        System.out.println(this.name + "is shopping!");  //誰調用就打印誰
​
        this.pay();
        
        //省略this
        pay();
    }
​
    //再定義一個實例方法
    public void pay(){
        System.out.println(name + "付錢付錢");
    }
}
            /*
            jackis shopping!
            jackis shopping!
            jack付錢付錢
            jack付錢付錢
            分界線===============================
            roseis shopping!
            roseis shopping!
            rose付錢付錢
            rose付錢付錢
            */

得出:在一個實例方法當中可以直接去訪問其它的實例方法

代碼

public class ThisTest {
​
    int i = 10;
​
    public static void main(String[] args) {
​
        //System.out.println(i);  //錯誤: 無法從靜態上下文中引用非靜態 變量 i。因爲main方法有static,i是實例變量,要用引用.去訪問
​
        //System.out.println(this.i); // 錯誤: 無法從靜態上下文中引用非靜態 變量 this。因爲 main 方法帶有 static,不能用 this(代表當前對象)
​
        ThisTest tt = new ThisTest();
​
        //通過引用訪問
        System.out.println(tt.i);
    }
}

得知:

  • 在 static 的方法中不能直接訪問實例變量,須先自己創建一個對象,通過“引用”可以去訪問。

  • 在 static 的方法中不能通過 this 訪問實例變量,因爲在 static 方 法中是不能存在 this 的。

同理:

  • main 方法中無法直接調用實例方法 ,因爲實例方法也必須要new對象,通過引用調用

this 使用在構造方法中,this(實際參數列表);調用另一個有參的構造方法

  • this();語法要在同一個類中使用

  • this();只能在構造方法第一行,前面不能有其他代碼

public class ThisTest02{
    public static void main(String[] args){
​
        //調用無參構造
        Date d1 =  new Date();
        d1.detail();
        
        //調用有參構造
        Date d2 = new Date(2020,06,19);
        d2.detail();
    }
}
​
    
class Date{
    private int year;
​
    private int month;
​
    private int day;
​
​
​
    //業務要求,默認創建的日期爲 1970 年 1 月 1 日
    //無參構造方法
    public Date(){
        /*
        this.year = 1970;
        this.month = 1;
        this.day = 1;
        */
        //System.out.println("隨便寫一行代碼在this()前");  //錯誤: 對this的調用必須是構造器中的第一個語句
​
        //無參構造方法調用有參構造方法1行代碼
        this(1970,1,1);  
    }
​
    //有參構造方法
    public Date(int year,int month,int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
​
    //定義一個打印年齡的方法
    public void detail(){
        System.out.println(year + "年" + month +"月" + day + "日");
    }
​
    //set和get
    public void setYear(int year){
        this.year = year;
    }
    
    public int getYear(){
        return year;
    }
​
    public void setMonth(int month){
        this.month = month;
    }
​
    public int getMonth(){
        return month;
    }
​
    public void setDay(int day){
        this.day = day;
    }
    
    public int getDay(){
        return day;
    }
}

小總結:

  • 代碼封裝,屬性一般都私有化

  • 都要有兩個構造方法,一個無參構造,一個有參構造。(對象屬性的 初始化)

  • 都要有對應的set和get方法,這是封裝的規定,就算暫時用不到也要寫。

  • 封裝的get方法要指定返回值的類型,不需要傳參。

  • 封裝的set方法不需要返回值,所以返回值類型固定寫法void,但是需要傳參數。

  • 只要調用的方法a和被調用的方法b是在同一個類裏面,this.和類名.可以省略

銀行存取款代碼:其實這3個類寫入3個文件內比較好

public class TestCustomerAccount{
​
    public static void main(String[] args){
        
        Account a = new Account("10086",1000,0.0023);
​
        Customer c = new Customer("smth",a);
​
        //存100
        //取960
        //取200
​
        c.getAct().deposite(100);
        c.getAct().withdrow(960);
        c.getAct().withdrow(2000);
        
    }
}
​
//客戶類
class Customer{
​
    private String name;
    
    private Account act;
​
​
    //構造方法
    public Customer(){
    
    }
    
    //有參構造
    public Customer(String name,Account act){
        
        this.name = name;
​
        this.act = act;
    }
    
​
    //set 和 get方法
​
    public void setName(String name){
    
        this.name = name;
    }
​
    public String getName(){
​
        return name;
    }
​
    public void setAct(Account act){
​
        this.act = act;
    }
​
    public Account getAct(){
        return act;
    }
}
​
//賬號類
class Account{
    private String id;  
    private double balance;  //餘額實例屬性
    private double annualInterestRate;   //年利率實例屬性
​
        
    //無參構造
    public Account(){
    
        
    }
    
    //有參構造,
    public Account(String id, double balance, double annualInterestRate){
​
        //構造方法是創建對象的時候,對象的屬性初始化
        this.id = id;
        this.balance = balance;
        this.annualInterestRate = annualInterestRate;
    }
​
​
    //各屬性set和get,這裏是後期查詢和修改需要
    //爲啥每個類都寫set和get方法,用不到也要寫,因爲這是“封裝”的規定
    public String getId(){
        return id;
    }
​
    public void setId(String id){
        this.id = id;
    }
​
    public double getBalance(){
        return balance;
    }
​
    public void setBalance(double balance){
        this.balance = balance;
    }
​
    public double getAnnualInterestRate(){
        return annualInterestRate;
    }
​
    public void setAnnualInterestRate(double annualInterestRate){
        this.annualInterestRate = annualInterestRate;
    }
    
    
    //存錢方法
    //存錢要傳一個參數告訴存多少錢
    
    public void deposite(double money){
    
        //this.balance += money;
        
        this.setBalance(this.getBalance() + money);
        System.out.println("存款成功" + money);
        
    }
​
​
    //取錢方法
    //取錢需要傳一個參數告訴取多少錢
    public void withdrow(double money){
        if(money > this.getBalance()){
            System.out.println("餘額不足,取款失敗");
            return;
        }
        this.setBalance(this.getBalance() - money);
        System.out.println("取款成功"+ money);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章