天天看點

Java SE day13定義注意調用的屬性與方法差別多态用途父子類之間的類型轉換instanceofnative 本地的Object 類==号與equals方法接口

多态

  • 定義
  • 注意
  • 調用的屬性與方法差別
  • 多态用途
  • 父子類之間的類型轉換
  • instanceof
  • native 本地的
  • Object 類
  • ==号與equals方法
  • 接口

定義

定義:同一行為,具有多個不同的表現形式
前提:父子類或接口實作,必須有重寫,父類引用指向子類對象。
           

注意

注意:
	是用不了子類獨有的内容,
	因為名義是父類的類型,隻能調用父類存在的,如果子類有重寫父類的方法,則可以調用重寫的方法。
           

調用的屬性與方法差別

變量看類型,方法看對象。
           
Person per1 = new Student();
per1.name;	// 這個是父類的,因為屬性定義是在父類對象的,即便重寫了也是父類的
per1.study();	// 方法的實際對象是子類對象,調用者是實際的子類對象
           

多态用途

多态參數:
		用父類作為方法的參數,以便能夠傳遞所有的子類對象。
		以下調用method方法,等價于:
					Person person = employee;
           
public class Test {
    public static void main(String[] args) {
        Employee employee = new Employee();
        method(employee);
        Student student = new Student();
        method(student);
    }
    public static void method(Person person){
        person.eat();
    }
}
           
多态數組:
		用父類數組引用來接收子類數組對象,避免代碼重複。
		以下代碼,兩者是差不多的。
           
Employee[] employees = new Employee[5];
        Student[] students = new Student[5];

        Person[] people = new Person[10];
        people[0] = new Student();
        people[1] = new Employee();
           

父子類之間的類型轉換

1,自動轉換(向上轉型  就是多态) 小 --> 大
           
2,強制轉換(向下轉型) 大 --> 小
           

與以下代碼類似:

double d = 1.0;

int i = (int)d;

想要調用子類特有的屬性或方法。

文法:

子類類型 對象名 = (子類類型)父類引用;
           
Person person = new Employee();// 或者這樣,Person person = new Person();,明顯這樣轉型再向下轉型不合适。
Employee employee = (Employee)person;// 這樣就可以調用Employee的是以屬性方法了。
           
// 如下代碼會在編譯時通過,但運作報錯
Person person = new Employee();
Student student = (Student)person;
           

報錯内容如下:

java.lang.ClassCastException:

對象指向錯誤,一類常見錯誤,因為父類指向了錯誤的子類導緻。

避免方法:

instanceof

判斷前面的對象是否屬于後面的類型或者是後面類型的子類。

boolean flag = employee instanceof Person;
        System.out.println(flag);
        flag = student instanceof Person;
        System.out.println(flag);
           

應用,編寫函數,傳入子類對象,判斷屬于哪個子類,并調用對應對象的特殊方法。

Student student = new Student();
        method(student);
        Employee employee1 = new Employee();
        method(employee1);

public static void method(Person person){
        if(person instanceof Employee){
            ((Employee) person).working();
        }else if(person instanceof Student){
            ((Student) person).studying();
        }
    }
           

注意程式設計規範,盡量不要使用轉型。聲明時可以使用自己對象類型的對象指向自己類型的空間。

調用方法時,使用父類作為參數,在傳遞時會自動向上轉型(多态)。

native 本地的

隻能修飾方法,一般追蹤源碼的時候會看到,用C寫的代碼,但可以用Java調用,native修飾的方法可以被重寫。

Object 類

Object類作為Java的根類,它的方法在繼承後可以重寫。

toString()的重寫	
           

可以傳回一段描述你寫的類的基本情況的字元串,在

System.out.println()函數中,如果有類的對象直接在裡面,調用的則是實際是該類的toString()傳回的字元串。
           

對于回收機制函數,當jvm調用垃圾回收機制的時候,會調用以下函數。

finalize(),任何類可以重寫該方法。
           

另外提一下,呼叫垃圾回收機制來回收垃圾的函數

system.gc(); 直接使用即可。
           

==号與equals方法

1, ==,  表示的是兩個變量的位址是否相同。
		 注意, 一般常量都存儲在常量池裡,它的位址是共用的。也就是說:
           
String string = "java";
String string2 = "java";
System.out.println(string==string2);
/** 輸出為 true

           
而,以下代碼跑出來的卻是 false 的:
           
String string = "java";
String string2 = new String("java");
System.out.println(string==string2);
/** 輸出為 false

           
2, equals()方法,先來看看源碼:
           

這是Object類的equals()方法。

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

發現與==的用法相同!

然後看看 String類重寫的equals源碼:這是比較String類對象的值。

public boolean equals(Object anObject) {
// 位址相同傳回true
        if (this == anObject) {
            return true;
        }
        // anObject是否是String的子類,否傳回 false
        if (anObject instanceof String) {
        // 将anObject類型轉換為String類型的anothorString
            String anotherString = (String)anObject;
            // 字元串存儲在value的字元數組中,求其長度,就是字元串的長度n
            int n = value.length;
            // 判斷長度是否相同
            if (n == anotherString.value.length) {
            	// 将this的字元串指派給v1[] anotherString指派給v2[]
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                // 逐個比較字元串的每個字元是否相同
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
           

接口

接口文法:

【public】 interface 接口名 {    }
 JDK1.8之前:
 	接口中的成員變量:靜态常量,必須初始化。
 	接口在的成員方法:公有的抽象方法,使用時必須重寫。
 	無:構造器,,初始化塊。
 特點:
 	接口不能執行個體化對象
 	隻能作為父類(父級接口)
 		子類繼承父類,,,實作類實作父接口
 	實作類實作父接口,并且實作父接口的所有的抽象方法
 		public class Aircraft implements Fly{ 抽象方法實作 }
 		一個類隻能有一個類,但可以有多個接口
 關系:
 	類與類之間: 單繼承
 	類與接口之間:多實作
 	接口與接口:多繼承