根據java 中的例子聯想到的constructor ,父類,子類

[size=xx-large]例一:[/size]
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;
pt.shout();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
void haha(){
System.out.println("can creat a method here? No");
}
}
}

當按照上面的方法書寫時,程序提示錯誤, 提示Syntax error on token(s), misplaced construct(s)
修改後如下:
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;

pt.shout();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
/* void haha(){
System.out.println("can creat a method here? No");
}*/
}
}

程序成功運行, 得到:age is 10
[size=xx-large]結論:[/size]constructor 有兩個方面的特性:一是名字得和class 得名字一致,二是它是一種特殊的方法(因此具有一般方法的特性),特別之處在於它不會返回值。在java 裏面, 方法是不可以嵌套創建的, 如果要在一個方法裏面用到新的方法, 得通過call, 而不是直接建立一個新的方法在裏面而產生像上面那樣的錯誤。
[size=xx-large]例二:[/size]
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;
// pt.shout();

}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
thingsoutstatic();
}
}

能夠成功運行,結果:method useful in constructor
[size=xx-large]結論:[/size]在constructor 裏面, 我們能夠去call 另一個方法, 當對象被創建時, 就會call constructor, constrctor 裏面的任何屬性(呵呵,這個屬性好像是屬於該class 的, 不是construcor單獨擁有的,constructor 也是class 的屬性呢!)都開始copy 到對象中,包括constructor 裏面所call的方法, 簡單一點說:constructor 是一種特殊的屬性,在每次創建對象時, 就會將該類的屬於promitive data type 的屬性copy 到對象空間中,並在對象空間中創建一個reference的空間指向該constructor.
[size=xx-large]例三:[/size]
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;
// pt.shout();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
shout();
}
}

運行結果:age is 0
[size=xx-large]結論:[/size]如果方法在constructor 裏面, 就是任何方法運行結果都回一模一樣,值也不會有變化,而constructor 裏涉及到的變量的值就會是class 屬性, 而不是對象屬性。要打印出變量屬性, 得直接call shout() method.
[size=xx-large]例四:[/size]
public class Tryha{

public static void main(String args[]){
Pt pt;
pt=new Pt();
pt.age=10;
pt.shout();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}


public Pt(){
}
}

運行結果:age is 10
[size=xx-large]結論:[/size]對象現將類的值儲存(此時已經從類的屬性變成對象的屬性了), 然後可以修改成自己單獨擁有的值,從自己這裏call 的方法當然是屬於自己的,於是所使用的屬性自然也是對象的屬性了。(把constructor 當成一張設計圖,class 想成構思,object 想成具體物體, 那麼call constructor 時就是直接使用的這個構思的設計圖, 而call object 得method 時, 該實現的方法也都得到實現了 , 當然得用object 自己的東西了)好難囉嗦清楚!!!
[size=xx-large]例五:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1();
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
System.out.println("super constructor");
}
}

class Pt1 extends Pt{
public Pt1(){
System.out.println("child constructor");
}
}

結果顯示:
super constructor
child constructor
[size=xx-large]結論:[/size]每一個子類的對象創建都會先call 父類的構造器,然後在call 子類的構造器 (絕對不存在什麼子類構造器覆蓋父類構造器的問題哦,像一像,子類的產生本來就要有父類的構造器嘛,而且子類不就是根據父類來的嗎?那麼通知父類一聲也是應該的, 呵呵,版權問題嘛!)
[size=xx-large]例六:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(){
System.out.println("super constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
public Pt1(int a){
System.out.println("child constructor");
}
}

結果顯示:
super constructor
child constructor
[size=xx-large]結論:[/size]和子類constructor 的parameter無關,只要父類中存在super(), 而你在子類的構造器中沒有特別去call 其他的super(int a)這種帶parameter 的構造器,那麼在產生子類對象時, 所調用的就是先call super(), 然後在子類。
[size=xx-large]例七:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
public Pt1(int a){
System.out.println("child constructor");
}
}

結果該程序不能運行,提示錯誤:Implicit super constructor Pt() is undefined. Must explicitly invoke another constructor
[size=xx-large]結論:[/size]如果在子類裏沒有call 父類的constructor, 那麼它會自己去call super() 這個constructor, 此時父類裏必須存在constructor.
[size=xx-large]例八:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
public Pt1(int a){
super(a);
System.out.println("child constructor");
}
}

結果顯示:
super constructor 2
child constructor
[size=xx-large]結論:[/size]在沒有default 得super()存在的情況下,必須在子constructor 中call 父類已經存在的constructor.
[size=xx-large]例九:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
public Pt1(int a){
super(int c);
System.out.println("child constructor");
}
}

程序錯誤, 提示Syntax error on token "int", delete this token, 但是一旦delete int 後,就會提示c cannot be resolved
[size=xx-large]結論:[/size]不要忘記了在java 中任何變量在使用前都得初始化(class 得properties 可以不用開始賦值,因爲class 會自動初始化所有的properties, 但是你要初始化也是可以的), 在上面的例子九中,運行到super (int c )時, 程序發現c並沒有值,所以程序報錯。
[size=xx-large]例十:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
int c=0;
public Pt1(int a){
super(c);
System.out.println("child constructor");
}
}

程序出錯, 提示Cannot refer to an instance field c while explicitly invoking a constructor
[size=large]可以修改爲:[/size]
public class Tryha{

public static void main(String args[]){
Pt1 pt1;
pt1=new Pt1(5);
}
}

class Pt{
int age;
void shout(){
System.out.print("age is "+age+" ");
}

void thingsoutstatic(){
System.out.println("method useful in constructor");
}

public Pt(int a){
System.out.println("super constructor 2 ");
}
}

class Pt1 extends Pt{
static int c=0;
public Pt1(int a){
super(c);
System.out.println("child constructor");
}
}

爲什麼這裏加上static 後程序就沒有問題了?
[size=xx-large]猜測原因是:[/size]有constructor不一定表示創建了對象, (儲存對象字段的空間和static 字段的空間是不相同的),而在constructor中指向instance data field 實例字段是不安全的, 因爲這個實例 有可能根本就不存在, 而static 並不屬於對象空間, 所以static可行。
本文轉載自-和訊博客-Robin's Blog-ousys
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章