動手動腦,11.9
- 為什麽子類的構造方法在運行之前,必須調用父類的構造方法?能不能反過來?為什麽不能反過來?
構造函數的功能主要用於在類的對象創建時定義初始化的狀態。構造一個對象,先調用其構造方法,來初始化其成員函數和成員變量。
子類擁有父的成員變量和成員方法,如果不調用,則從父類繼承而來的成員變量和成員方法得不到正確的初始化。
不能反過來調用也是這個原因,因為父類根本不知道子類有什麽變量,子類也得不到初始化的父類變量.所以程序不能運行。
2.不可變的“類”有何用?
可以方便和安全地用於多線程環境中,訪問它們可以不用加鎖,因而能提供較高的性能。
知識點:(子類與父類方法間的關系 擴充(Extends)
覆蓋/重寫(Override):子類父類定義了完全一樣的方法
重載(Overloads):子類有父類的同名方法,但兩者的參數類型或參數數目不一樣)
3.
public class ExplorationJDKSource {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(new A());
}
}
class A{}
public void println(Object x),這一方法內部調用了String類的valueOf方法。
valueOf方法內部又調用
public String toString() {
return getClass().getName() +"@" +
Integer.toHexString(hashCode());
}
- 我們來看一段代碼:
- 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()方法。
4.在子類中,若要調用父類中被覆蓋的方法,可以使用super關鍵字:
class Father
{
public void display()
{
System.out.println("Father");
}
}
class Son extends Father
{
public void display()
{
super.display();
System.out.println("Son");
}
}
public class Teost {
public static void main(String []args)
{
Son c=new Son();
c.display();
}
}
- 怎樣判斷對象是否可以轉換?
例: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));
}
}
6.現在有三個類:
class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}
針對每個類定義三個變量並進行初始化
Mammal m=null ;
Dog d=new Dog();
Cat c=new Cat();
下列語句哪一個將引起編譯錯誤?為什麽?哪一個會引起運行時錯誤?為什麽?
m=d;
d=m;
d=(Dog)m;
d=c;
c=(Cat)m;
d=m 編譯錯誤,基類轉換成子類需要強制轉換,d=c,錯誤,兩個對象不能互換。
7.請看以下“變態”的類,下述代碼的特點是:
子類和父類定義了一模一樣的字段和方法
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
你如何解釋會得到這樣的輸出?
當子類與父類擁有一樣的方法,並且讓一個父類變量引用一個子類對象時,到底調用哪個方法,由對象自己的“真實”類型所決定,這就是說:對象是子類型的,它就調用子類型的方法,是父類型的,它就調用父類型的方法。
這個特性實際上就是面向對象“多態”特性的具體表現。
當子類與父類有相同的字段,則子類中的字段會代替或隱藏父類的字段,子類方法中訪問的是子類中的字段(而不是父類中的字段)。如果子類方法確實想訪問父類中被隱藏的同名字段,可以用super關鍵字來訪問它。
如果子類被當作父類使用,則通過子類訪問的字段是父類的。
動手動腦,11.9