1. 程式人生 > >動手動腦4

動手動腦4

 

1.TestInherits.java

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

        	Child c = new Child();
  }

}

  輸出結果:

修改程式碼:

  輸出結果:

結論:通過 super 呼叫基類構造方法,必須是子類構造方法中的第一個語句。

 

2. 為什麼子類的構造方法在執行之前,必須呼叫父類的構造方法?能不能反過來?為什麼不能反過來?

構造方法用於對基類的初始化。當構造一個物件時,先呼叫建構函式對成員函式和成員變數進行初始化,。子類繼承了父類的成員函式和成員變數,若不進行呼叫,則不會對父類的初始化。

3.ExplorationJDKSource.java

public class ExplorationJDKSource {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(new A());
	}

}

class A{}

  

在編譯原始碼時,當遇到沒有父類的類時,編譯器會定義的預設的父類(一般為Object),public void println(Object x),這一方法內部呼叫了String類的valueOf方法。valueOf

方法內部又呼叫Object.toString方法:

public String toString() {

return getClass().getName() +"@" +

Integer.toHexString(hashCode());

}

 

4.

public class Fruit
{
		
	public String toString()
	{
		return "Fruit toString.";
	}

	public static void main(String args[])
	{
		Fruit f=new Fruit();
		System.out.println("f="+f);
	//  System.out.println("f="+f.toString());
	}
}

  輸出結果:

 

 

結論:在+”運算中,當任何一個物件與一個String物件,連線時,會隱式地呼叫其toString()方法,預設情況下,此方法返回“類名 @ + hashCode”。為了返回有意義的資訊,子類可以重寫toString()方法。

5. 方法覆蓋

 

public class parents {
public void parents(){
	System.out.println("parent!");
}
public void parent1(){
	System.out.println("parent1!");
}
}
public class child extends parents {
public void child(){
        super.parents();
}
public void parents(){
	System.out.println("child");
}
public static void main(String[]args){
	child ch=new child();
	ch.parents();
	ch.child();
	ch.parent1();
}
}

 

  輸出結果:

 

6. TestInstanceof.Java

public class TestInstanceof
{
	public static void main(String[] args) 
	{
		//宣告hello時使用Object類,則hello的編譯型別是Object,Object是所有類的父類
		//但hello變數的實際型別是String
		Object hello = "Hello";
		//String是Object類的子類,所以返回true。
		System.out.println("字串是否是Object類的例項:" + (hello instanceof Object));
		//返回true。
		System.out.println("字串是否是String類的例項:" + (hello instanceof String));
		//返回false。
		System.out.println("字串是否是Math類的例項:" + (hello instanceof Math));
		//String實現了Comparable介面,所以返回true。
		System.out.println("字串是否是Comparable介面的例項:" + (hello instanceof Comparable));
		String a = "Hello";
		//String類既不是Math類,也不是Math類的父類,所以下面程式碼編譯無法通過
		//System.out.println("字串是否是Math類的例項:" + (a instanceof Math));
	}
}

  

 

輸出結果:

7. 型別轉換

 

 

class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}

public class TestCast
{
	public static void main(String args[])
	{
		Mammal m;
		Dog d=new Dog();
		Cat c=new Cat();
		m=d;
		//d=m;
		d=(Dog)m;
		//d=c;
		//c=(Cat)m;

	}
}

  

結果:d=m;  d=c;有錯誤,c=(Cat)m正確

結論:在繼承中,子類可以自動轉換成父類,但父類轉換成子類只有引用型別真正身份才會轉換成功,否則會失敗。

 8.

public class ParentChildTest {
	public static void main(String[] args) {
		Parent parent=new Parent();
		parent.printValue();
		Child child=new Child();
		child.printValue();
		
		parent=child;
		parent.printValue();
		
		parent.myValue++;
		parent.printValue();
		
		((Child)parent).myValue++;
		parent.printValue();
		
	}
}

 

 

 

 

 

結論:由此可得Java的一些語法特性(多型):

當子類與父類擁有一樣的方法,並且讓一個父類變數引用一個子類物件時,到底呼叫哪個方法,由物件自己的“真實”型別所決定,這就是說:物件是子型別的,它就呼叫子型別的方法,是父型別的,它就呼叫父型別的方法。

如果子類與父類有相同的欄位,則子類中的欄位會代替或隱藏父類的欄位,子類方法中訪問的是子類中的欄位(而不是父類中的欄位)。如果子類方法確實想訪問父類中被隱藏的同名欄位,可以用super關鍵字來訪問它。 如果子類被當作父類使用,則通過子類訪問的欄位是父類的。

因此,我們進行程式設計時應避免子類與父類同名的欄位!

9.

public class TestPolymorphism
{


    public static void main(String args[])
    {

        Parent p=new Parent();

        p.Introduce();

        System.out.println(p.value);

        p=new Son();

        p.Introduce();

        System.out.println(p.value);

        p=new Daughter();

        p.Introduce();

        System.out.println(p.value);


    }

  

多型程式碼:當多個類實現同一介面(或派生自同一抽象類)時,針對這些類所建立的物件呼叫介面所定義的方法時,會分別呼叫相應的類的具體實現程式碼。