靜態方法和靜態屬性

不全都是動態

我們都知道,方法是放在實例裡運行的。也就是說方法執行的結果是依據實例屬性而來的,而實例的屬性是根據當前狀態而變化的——我們稱其為“動態”。

但真的全都是動態的嗎?其實不是,有些方法它會直接根據你的調用而給出結果,並不需要依據實例屬性的變化來產生變動——也就是說它是無論如何都會產生確定的結果的,我們稱這樣的方法為靜態方法,它是靜態的。

我們來舉個栗子看看:

這是一個普通的類和方法,我們創建不同的 Gun 實例,那麼 fire() 方法的執行結果也會不同,有的子彈打完了,有的則沒有打完。

現在我在這個類裡邊插入了一個判斷兩個數字大小的方法,這個方法無論實例在什麼狀態,它都會返回確定的結果——哪個數字大就返回哪個,和實例的狀態——打了多少槍沒有關係,我們就說這個方法可以設置為靜態方法(用 static 前綴標記出來)。如你所見,靜態方法的調用不需要實例,直接使用點運算符來調用。

“一種不依靠實例變量也就不需要對象的行為。“

類型方法

我們使用 static 這個前綴來標記靜態方法,由於我們調用靜態方法並不是從特定的實例中調用,而是直接從類裡調用,我們也說這個方法是在“類”層面執行,所以靜態方法也就會被叫做“類型方法“。

同樣的原因,也會導致類型方法不針對特定的實例,所以它不能訪問到實例屬性——類型方法不能訪問動態屬性。它根本不在堆上,自然找不到堆上的某個實例裡的某個屬性了!

所以再一次同樣的原因,類型方法也是不能調用動態方法的——動態方法在堆上,在實例裡邊啊!

類型屬性

我們說了類型方法不能訪問動態的屬性,那自然就會有靜態的屬性出現啦!當然,動態的方法也可以訪問靜態的屬性的——考慮到靜態又是類層面的,所以它也會被稱作“類型屬性“。

同樣的原因,對同類的所有對象共享!

沒錯!同類下的對象互相通信就靠它呢!我們來舉個栗子看看:

我們增加了一個監控所有槍發射的子彈數量,一共用三個實例開了五槍,但 total 都記錄了下來——也就是說類型屬性對同類的實例來說是全局的,它不屬於某個對象,而是屬於這個類下所遇對象的!

實例屬性——每個實例一個;

類型屬性——每個類一個!

靜態和繼承

如果你細心,可能會發現類型屬性和類型方法不能夠被覆蓋!如果你覆蓋一個類型方法,則會被提示:你正在覆蓋一個標記未 final 的方法!

所以,如果需要能夠被覆蓋,你需要使用 class 前綴而不是 static 來標記類型方法,這樣它就允許被子類覆蓋掉了。

本文由 落格博客 原創撰寫:落格博客 » 靜態方法和靜態屬性

轉載請保留出處和原文鏈接:https://www.logcg.com/archives/1136.html

關於作者

R0uter

如非聲明,本人所著文章均為原創手打,轉載請註明本頁面鏈接和我的名字。

發表評論

您的電子郵件地址不會被公開. 必填字段標 *