深入Java類、對象 與 Static

Yangcl 11年前發布 | 5K 次閱讀

深入Java類、對象與Static

 今日閑來無事,室外都快成烤箱了。。。So,沒事做就仔細研究了一下Java的類、對象和Static的關系。剛開始學習Java的時候,對著Core Java看,看了好久也沒明白什么是類,什么是對象,還有這個頭疼的Static。隨著工作了一段時間,類和對象這些概念有了一些理解,但一直沒有仔細深入的分析。期間也在網上、各大論壇求解過像Static做用什么的,但一直不得要旨。今天就來仔細總結一下。隨著發掘的深入,我發現Java的類、對象和Static這三個概念是密切相關的,他們不能分開。

 在面向對象中,有兩個重要概念:類和對象。對象也被稱作“實例(instance)”那么究竟什么是類?類是某一批對象的抽象。對象是一個具體存在的實體。我這么說,你看懂了嗎?我覺得可能大部分人還是看不懂,因為這個定義太特么抽象了。你是不是再說:“U TM Say What 呢?” Well~ Keep Easy~ 一會兒我用“人”類來給你做個解釋。

 重定義你的觀念 -> 接口:在JavaC#中,接口這個概念可不是你想的那么簡單。在很多書和論壇中大家對接口的一般定義為:比抽象類更加徹底的抽象類-interface。接口里不能包含普通方法,只能是抽象方法云云。但是這里我要告訴你的是:接口,他代表了一個類型!就是說:你這個類,只要實現了我的接口,你便擁有了我的類型特征。Java中提倡單一繼承,多重實現。你可以implements多個接口,也就是說你定義的類將擁有多重類型特征。比如在代碼程序中我們定義了一個接口:Person,他的實現類是YellowPerson你在編程的時候可能會用到類型匹配的邏輯,比如:如果你的類是Person類,那么執行代碼邏輯。YellowPerson  yp = new YellowPerson();  if(yp.IsPartTypeOf (Person)) ……當然這里的IsPartTypeOf方法是你要自己寫的。接口作為順帶介紹,與本文關聯并不大。你要知道他還有類型的意義就夠了。下面用代碼說明類、對象和Static

public interface Person

{

              void say();

              void head();

              void body();

              void armsAndlegs();//四肢

             

              public static final int eyes =2;

              public static final int mouth = 1; 

}

public class YellowPerson implements Person

       private static int ears = 2; 

       private static int nose = 1;

      

       private String sex ;

       private String skin

        

       public void head()

       {

              System.out.println("我繼承了人類,我有:" + this.eyes 

                            +  " 眼睛和 " + this.mouth + " 張嘴");

       }

       public void body()

       {

              System.out.println("我還有: " + ears  + " 耳朵;: " +

                            nose + " 個鼻子");

       }

      

       public void armsAndlegs()

       { 

              String a = getSex();

              String b = getSkin();

              System.out.println("人的性別和膚色是不固定的,我是 " + a + b+ "皮膚");

       }

       public void say()

       {

              this.head();

              this.body();

       }

       //########################################

       public String getSex() {

              return sex;

       }

       public void setSex(String sex) {

              this.sex = sex;

       }

       public String getSkin() {

              return skin;

       }

       public void setSkin(String skin) {

              this.skin = skin;

       }

}

public class Test

{

       public static void main(String[] args)

       {

              YellowPerson  yp = new YellowPerson();

              yp.say();

              yp.setSex("男人");

              yp.setSkin("黃色");

              yp.armsAndlegs();

              System.out.println("眼睛數量:"+yp.eyes);

       }

}

打印結果:

我繼承了人類,我有:2 眼睛和 1 張嘴

我還有: 2 耳朵;: 1 個鼻子

人的性別和膚色是不固定的,我是 男人黃色皮膚

眼睛數量:2

 

靜態變量代表是這個類的固有屬性。比如正常人肯定有2個眼睛、一張嘴、2個耳朵,一個鼻子等等。但是這個人的名字、性別、膚色、身高、體重都是不確定的,所以這些不是靜態屬性。我們在Test.java中調用YellowPerson的時候產生一個對象:ypyp對象中就已經包含了所有 “靜態屬性” 值:鼻子、眼睛、嘴等等。你用yp直接可以調用該對象包含的static變量,比如:“眼睛數量:2”。但是非靜態的普通屬性你則需要設定。

也就是說:作為“類”來講,他定義了很多內容,其中有固定的,有的不是固定的,固定的都是static的;“類”更像是一個模板,而對象則是從這個模板中復制出來的東西。凡是模板都有固定的東西,比如做月餅的模子,他有固定的花紋,但月餅餡不同;“人”這個模板則固定有頭、身體、四肢、五官、器官等等static屬性,而姓名、性別、身高等等每個人不同,則是普通屬性。從這個角度講:我們日常說的人其實都是“人”這個類的實例(對象),而不是人類。就是說:當你在其他地方調用一個類的時候,他的靜態屬性已隨著對象的初始化復制而出,你直接可以使用,但是普通屬性你需要設定,或者更改。比如上述代碼中的性別和膚色等。注意:靜態屬性也可以不通過去創建對象來調用,直接用類名+屬性或方法就可以,如:YelloPerson.eyes

       那么對象如何初始化?

    通過構造器,也就是常說的構造函數。每一個類都有一個默認的構造函數。構造函數是用于構造一個類實例的根本途徑,即:對象初始化。(順便提一句方法用于定義類或類實例的行為特征與功能實現。構造函數與方法的區別是沒有修飾詞。) 你要時刻記得:對象即實例。對象的創建和使用如下,很簡單但很容易被忽略:

YellowPerson  yp ; //定義一個YelloPerson類型的變量

yp = new YellowPerson(); //通過new 關鍵字調用YelloPerson類的構造函數,返回一個類實例

                                   //將實例付給yp變量

因為調用的是類的構造函數,所以YelloPerson后面會有括號。new YellowPerson()即為實例(對象)

    總結一句:你不是人這個類我也不是人這個類,所有活著的人都是“人”的實例(對象)

 



       不得不修改一下,我在寫這篇博客的時候,對類、對象、實例和Static的理解存在不足的地方,現在給予糾正。
       首先是對象。在《Think In Java》和《Java核心技術中》給予對象的定義是這樣的:“萬物皆對象。”  這樣放到現實中來講,包括類以及由類產生的實例都屬于對象的范疇。類、對象和類實例之間的關系應該是這樣來描述:【類】是一個被定義的模板(包括各種具體屬性,如字段、方法);【類實例】是從這個模板中復制出的一個對象;而【對象】應該包括【類】和【類實例】。所以說:“對象即實例”,這句話本身存在缺陷,是錯誤的。應該這樣描述更加確切:【new 一個類的構造函數產生的是一個類實例】,如果你硬說產生的是一個對象,這樣也沒錯,
只不過這樣顯得空乏,因為對象是一個全集的概念。如下舉例:

    yp = new YellowPerson(); //通過new 關鍵字調用YelloPerson類的構造函數,返回一個類實例   
在上面這段代碼中【
通過new 關鍵字調用YelloPerson類的構造函數,返回一個類實例】這樣描述要比【通過new 關鍵字調用YelloPerson類的構造函數,返回一個“對象”】這個描述更加準確。
       其次是“static”。上文中描述【
靜態變量代表是這個類的固有屬性】,這也是不確切的,是狹隘的理解,當然就是錯的。舉例如下:定義一個Person類,類中定義一個靜態屬性方法:
       public static int nose();
然后分別創建了10個Person類實例,但事實上這10個類實例只有一個nose()方法,并不是每一個類實例都包括了一個自己的nose()方法,即:他們公用一個nose()方法;如果這個比方在現實中發生,那么他們這10個人其實是連體嬰兒,因為他們公用一個鼻子。如果在Person類中nose()方法變成非static,而定義一些這樣的static方法:air()、water()、sunshine() ,那么會顯得更合理一些,也更說的通;因為這些方法是人類共同需要的、無法脫離的。
        在從內存中解釋,【static類型屬性和方法】在內存中只有一個地址,不是你有多少個類實例就會有多少個地址,你只是引用了這個地址。如果從這個角度講,那么當你設計一個程序的時候,事實上絕大多數的類是可以不包括【
static類型屬性和方法】,而單獨的設計一個類專門去做這件事。這樣在程序的可讀性和可維護性上也會好很多。

  



 













































 

 

 

 本文由用戶 Yangcl 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!