1. 程式人生 > >第三次動手動腦

第三次動手動腦

(一)

通過 super 呼叫基類構造方法,必須是子類構造方法中的第一個語句。在呼叫子類構造方法之前,必須先呼叫基類構造方法。

(二)

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

建構函式的主要作用是在定義物件時初始化物件,定義子類物件時會同時定義父類物件,然後呼叫父類構造方法將其初始化,再呼叫子類物件將其初始化,所以不能反過來。

(三)

package JavaApp;


public class ExplorationJDKSource {

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

我們得到了一個奇特的執行結果: [email protected]

為什麼??

在編譯原始碼時,當遇到沒有父類的類時,編譯器會將其指定一個預設的父類(一般為Object),而虛擬機器在處理到這個類時,由於這個類已經有一個預設的父類了,main方法實際上呼叫的是:
public void println(Object x),這一方法內部呼叫了String類的valueOf方法。
valueOf方法內部又呼叫Object.toString方法:
public String toString()
{

     return getClass().getName() +"@" + Integer.toHexString(hashCode());

}
hashCode方法是本地方法,由JVM設計者實現: public native int hashCode();所以出現上述結果。

(四)

package JavaApp;

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()); } }
一個字串和一個物件“相加”,得到以下結果:

f=Fruit toString.
f=Fruit toString.

為什麼??

當一個字串和一個物件連線時,物件會隱式的呼叫其toString方法。所以兩個輸出結果一樣。

(五)

在子類中,若要呼叫父類中被覆蓋的方法,可以使用super關鍵字。

package JavaApp;

class one
{
      public void one()
      {
          System.out.println("這是父類!");
      }
}

class two extends one
{
       public void one()
      {
          System.out.println("這是子類!");
          System.out.println("使用super關鍵字:");
          super.one();
      }
}

public class fugai {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
           two a=new two();
           a.one();
    }
}

執行結果:

這是子類!
使用super關鍵字:
這是父類!

 

(1)覆蓋方法的允許訪問範圍不能小於原方法。

(2)覆蓋方法所丟擲的異常不能比原方法更多。

(3)宣告為final方法不允許覆蓋。 例如,Object的getClass()方法不能覆蓋。

(4)不能覆蓋靜態方法。

(六)

下列語句哪一個將引起編譯錯誤?為什麼?哪一個會引起執行時錯誤?為什麼?

m=d;

d=m;

d=(Dog)m;

d=c;

c=(Cat)m;

package JavaApp;

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;

    }
}

子類物件可以賦給基類物件,基類物件賦給子類物件時必須強制轉換,同一父類派生下來的子類之間不可以賦值。

所以可以成立的有m=d;        d=(Dog)m;     c=(Cat)m;

(七)
package JavaApp;

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();
    }
}

class Parent{
    public int myValue=100;
    public void printValue() {
        System.out.println("Parent.printValue(),myValue="+myValue);
    }
}
class Child extends Parent{
    public int myValue=200;
    public void printValue() {
        System.out.println("Child.printValue(),myValue="+myValue);
    }
}

執行結果:

Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201