1. 程式人生 > 其它 >不規則窗體setMask()

不規則窗體setMask()

相信有一雙善於觀察的眼睛的你一定發現了,我們每次使用物件去.的時候,總是會有很多我們自己沒有寫過的方法。

就像這些:

我們明明沒有寫這些,為什麼會有呢?這就必須得提到我們的類的鼻祖:Object類了。

1.Object是什麼?

所有的類都直接或者間接的繼承了Object類。如果該類繼承了除Object類的其它類,則該類為間接的繼承Object類,若沒有繼承其它類,則為直接的繼承Object類,可以省略extends Object,也可以寫上。

那我怎麼知道這些方法是幹嘛的呀!又不是我寫的。

這個時候就需要我們的api幫助文件出場了,裡面詳細的記載了Object類的所有內容,包括所有方法的含義和使用等等。

2.api的使用

api是Application Programming Interface的縮寫,即應用程式程式設計介面。而api文件,,就像是說明書,裡面包含了Java已經定義好的類、介面、抽象類的詳細內容。

今後的學習幾乎都是參考api文件去學習api裡面的類、介面、抽象類的內容。

首先我們需要按照索引來搜尋我們想要查詢的內容:

輸入內容之後按回車:

但是可能有多個,因為有的是類,有的是介面(後續內容會講)

我們找到Object類:(可以先點選進去,不是就再搜尋一次點選另外一個)

可以看到關於這個類有特別詳細的解釋,往下滑有關於方法的特別詳細的解釋,(小tip:點選藍色的方法名就能直接跳轉),所以api文件是我們需要好好利用的一個工具。

api百度網盤連結

連結:https://pan.baidu.com/s/1t_cKercpOW3uWReREcf8ug
提取碼:p8yj

有需要自取~

3.Object常用方法

所有的類都擁有Object類的所有方法。

以下幾個方法必須掌握!

(1)hashcode()

//返回物件的雜湊碼值
public int hashCode()

hashcode()用於返回物件的雜湊碼值。雜湊碼值是物件在記憶體中的邏輯地址,是相對於真實地址經過一定的運算得到的一個整數,物件的引用地址儲存在棧中,真實的值存放在堆中,棧中的引用地址指向堆中的值。

例:

package com.dh.object;

public class HashcodeDemo {

    public static void main(String[] args) {

        //例項化一個物件
        HashcodeDemo hashcodeDemo = new HashcodeDemo();
        //得到物件的雜湊碼值
        int hashCode = hashcodeDemo.hashCode();
        //輸出該物件的雜湊碼值
        System.out.println(hashCode);

        //每個物件的雜湊碼值是不一樣的
        HashcodeDemo hashcode2 = new HashcodeDemo();
        System.out.println(hashcode2.hashCode());
    }
}

結果:每個物件的雜湊碼值一般來講是不一樣的

既然我們繼承了Object類,那我們也能重寫其方法。

如果要讓某個類的所有物件都返回相同的值,只需要重寫hashcode():

原本呼叫的是父類的hashcode()

@Override
public int hashCode() {
    return super.hashCode();
}

重寫:讓hashcode()的返回值為固定的數,則每一個物件都會返回這個值,就會讓每個物件hashcode()結果都相同。

package com.dh.object;

public class HashcodeDemo {

    @Override
    public int hashCode() {
        return 1000;    //任意int型別整數
    }

    public static void main(String[] args) {

        //例項化一個物件
        HashcodeDemo hashcodeDemo = new HashcodeDemo();
        //得到物件的雜湊碼值
        int hashCode = hashcodeDemo.hashCode();
        //輸出該物件的雜湊碼值
        System.out.println(hashCode);

        //每個物件的雜湊碼值是不一樣的
        HashcodeDemo hashcodeDemo2 = new HashcodeDemo();
        System.out.println(hashcodeDemo2.hashCode());
        
        System.out.println(hashcodeDemo.hashCode() == hashcodeDemo2.hashCode());
    }
}

結果:

(2)getClass()

//返回此Object的執行時類
//<>是泛型,後續會講到,可暫時去掉
public final Class<?> getClass()

首先需要明確的是,Java是強型別語言,嚴格區分大小寫,Class 是一個型別,和我們定義類使用的 class 關鍵字是不一樣的!

在執行Java程式的時候,首先會將.java檔案編譯成.class位元組碼檔案,如何把位元組碼檔案載入進記憶體,在Java中,萬事萬物皆為物件,所以jvm就認為該位元組碼檔案為一個物件,Class型別對應的物件就是:位元組碼檔案(.class)物件。

每個類只有一個.class檔案,可想而知,同一個類的例項同屬一個.class位元組碼檔案,所以getClass()的值也都是一樣的。

例:

package com.dh.object;

public class GetClassDemo {

    public static void main(String[] args) {
        //new一個物件
        GetClassDemo getClassDemo = new GetClassDemo();
        //使用getClass()獲得一個Class型別的物件
        Class aClass = getClassDemo.getClass();
        //輸出該物件
        System.out.println(aClass);

        //同一個類的例項使用getClass()因返回同一個值
        GetClassDemo getClassDemo2 = new GetClassDemo();
        System.out.println(getClassDemo2.getClass());
    }

}

結果:

getClass()的結果為:class 包名.類名。

getClass()是final修飾的,所以不能被重寫。

(3)toString()

//返回物件的字串表現形式
//返回值為:getClass().getName() + '@' + Integer.toHexString(hashCode())
//可以在IDEA這滑鼠放在toString()上,按ctrl,滑鼠左鍵進去看原始碼,原始碼例就是這樣寫的輸出
//Integer.toHexString():將十進位制轉換為十六進位制
public String toString()

例:

package com.dh.object;

public class ToStringDemo {

    public static void main(String[] args) {

        //new一個物件
        ToStringDemo toStringDemo = new ToStringDemo();
        //使用toString,返回該物件的字串表示形式
        String s = toStringDemo.toString();
        //輸出該物件的字串表現形式
        System.out.println(s);

        //不同物件的字串表現形式
        ToStringDemo toStringDemo2 = new ToStringDemo();
        System.out.println(toStringDemo2.toString());
    }
}

結果:

我們輸出物件,看看結果會是什麼:

System.out.println("============");
System.out.println(toStringDemo);
System.out.println(toStringDemo2);

觀察結果可得:直接輸出物件和輸出物件的toString()是一樣的。

如果輸出物件的值為這樣的話,就沒有什麼意義了是不是,這字串又看不懂,所以我們可以重寫一下toString(),用來輸出我們想要看到的物件,比如物件的屬性。

重寫toString():

package com.dh.object;

public class ToStringOverride {

    public String name;
    public int age;

    public ToStringOverride(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    //重寫Object的toString()
    public String toString() {
        return "name = "+this.name+"\tage = "+this.age;
    }

    public static void main(String[] args) {

        ToStringOverride toStringOverride = new ToStringOverride("Tom",18);
        //呼叫重寫後的toString()
        String s = toStringOverride.toString();
        System.out.println(s);
    }
}

結果:按照我們的格式輸出了資料。

可以看到,只是輸出當前的屬性,是很簡單的操作,但是卻要重複的寫,強大的IDEA已經給我們提供了快捷方式:alt+ins,選擇toString,再選擇你要的屬性:

@Override
public String toString() {
    return "ToStringOverride{" +
        "name='" + name + '\'' +
        ", age=" + age +
        '}';
}

方便快捷!

(4)equals()

//指示一些其他物件是否等於此。 
public boolean equals(Object obj) 

==和equals()都是用來判斷相等的,那它們有什麼區別呢?

== 和 equals()的區別
  • ==

    • 基本資料型別:比較的是值

    • 引用資料型別:比較的是記憶體地址

      package com.dh.object;
      
      public class EqualsDemo {
      
          public static void main(String[] args) {
      
              int a = 1;
              int b = 1;
              
              EqualsDemo equalsDemo1 = new EqualsDemo();
              EqualsDemo equalsDemo2 = new EqualsDemo();
      
              //==比較基本資料型別,比較的是值,值相等,結果為true
              System.out.println(a == b);
              //==比較引用資料型別,比較的是地址,每個物件的地址都不一樣,結果為false
              System.out.println(equalsDemo1 == equalsDemo2);
          }
      }
      
      

  • equals()

    • 引用資料型別:比較的是記憶體地址。(未重寫該方法時)

      原始碼:

      public boolean equals(Object obj) {
          return (this == obj);
      }
      

      equal方法本質上還是==比較。

      在上述程式碼中,新增使用equals比較的輸出語句:

      System.out.println("================");
      System.out.println(equalsDemo1.equals(equalsDemo2));//記憶體地址不一樣,輸出false
      

      結果:

    • 字串:比較的是字串的內容。(重寫了該方法)

String類重寫equals()

因為==就可以用來比較兩個引用資料型別的地址,如果equals()也是的話,就多餘了,所以,我們可以重寫equals()方法,讓它具有別的功能。String類就已經幫我們實現了這個功能。

String類重寫了equals(),用於比較字串的內容是否相等:

package com.dh.object;

public class EqualsOverride {

    public static void main(String[] args) {

        String s1 = "hello";
        String s2 = "hello";

        System.out.println(s1.equals(s2));
    }
}

我們將滑鼠移到equals上,ctrl+滑鼠左鍵點選進入原始碼:

//實現字串的值比較(看不懂可暫時不看)
public boolean equals(Object anObject) {
    if (this == anObject) {	
        return true;
    }
    if (anObject instanceof String) {
        String aString = (String)anObject;
        if (coder() == aString.coder()) {
            return isLatin1() ? StringLatin1.equals(value, aString.value)
                : StringUTF16.equals(value, aString.value);
        }
    }
    return false;
}

本人水平有限,若有錯誤,望指正,感激~