1. 程式人生 > >說說我對面對物件的理解

說說我對面對物件的理解

歡迎大家在茫茫博文中找到鄙人的陋文閱讀,希望可以給你一點程式設計上的幫助

  • 引用是面對物件的實現的本質
  • 物件的建立(介面,抽象類)
  • 面對物件程式設計的類(或者說封裝)和屬性的操作

引用是面對物件的實現的本質

面對物件的資料或者物件或者資料結構的操作實質上都是指標的操作或者引用型別,面對物件本質上就是“資料的封裝”(似乎說的很直接且沒有什麼營養),但是你建立一個物件(指標或者引用)總要指向一個記憶體區域的首地址,那麼這個地址區域就是你建立的或者指向的資料物件在記憶體中儲存的地方。

所以面對物件程式設計,你把方法,變數進行類封裝,那麼在記憶體中如果宣告這個類的物件,那就是建立一個地址區域將這個進行儲存。說白了,面對物件實際上是從結構程式設計上的資料進行封裝(在記憶體上就是區域化統一管理和指標定址)。

但是在高階的面對物件程式語言中沒有指標概念,通常上說:

class people;
people p = new people();

p就是建立的引用型別,實質上就是指標(再贅述一遍)

class people;
people p;
p = people1;

那麼p就指向people1

在面對物件中我們對資料結構物件操作,通常自己忘了物件本身是指標型別,而造成了資料的汙染。

1 | list1
2 | list2
3 | list3
4 | list4 這是一個map儲存的list資料結構

list p;
list li = data;
for
(int i = 0;i < map.size();i++) { p = map(String.valueof(i)); if(p.size()>5) p = li; }

物件的建立(介面,抽象類)

物件的建立是資料在記憶體中分配記憶體儲存區域的過程,也就是程式建立資料的過程。對於面對物件語言的編譯器,在編譯的過程中會載入類載入器去載入引入的類,但是這個過程並不涉及編寫的程式碼。編譯程式碼是使用載入的類建立資料(也就是宣告的物件),那麼物件的建立是面對物件資料建立的過程。所以在宣告一個介面,然後我們去擴充套件介面的時候(注意:這裡是宣告非抽象類)或者new 一個介面物件的時候,需要過載介面中的方法。因為宣告一個類,說明這個類是要被建立物件的,那麼擴充套件的介面也要被隨著這個物件建立而建立,因此我們需要對介面實現化(也就是過載或者實現介面的方法)。那麼為什麼抽象類在擴充套件介面的時候,為什麼可以不用實現介面方法呢?那是因為在面對物件中,抽象類不能用來建立物件(或者不可以直接用來資料實現化),而是需要子類或者其他的類來繼承,並且實現過載抽象方法。那麼其子類在建立物件的時候,那麼才會先走都父類(也就是抽象類)的構造方法去建立父類物件。
通過以上的一段闡述面對物件的基本機制,那麼應該對面對物件程式設計中物件建立這個過程的有了比較成熟的理解。總結就是物件的建立是實類資料記憶體化的過程,但是介面和抽象類不屬於實類,實類有繼承的抽象類或者擴充套件的介面,那麼實類是必須過載實現抽象方法的。直接使用 new 建立非實類(抽象類或者介面)的物件,那麼必須過載實現其抽象方法。
還有一點需要注意:對於類的繼承成員如果是protected或者public,那麼成員是被子父類共同使用的(下面具體細說)。

面對物件程式設計的類(或者說封裝)和屬性的操作(父類與子類共同使用繼承的資料)

可以想象,如果子類與父類不共同使用繼承的資料,那麼在Java裡面所有的類其實都源於object類,那麼我們一個工程裡面所有的類都會建立object中的資料。這樣會導致資料重複的讓人嘆之,object還有一級子類,下面對應的還有子類,那麼一級、二級子類也會重複建立資料,也是重複的讓人嘆之。這樣,一個簡單的程式會很耗記憶體。

class father{

public String name;

public int age;

private String secret;

public String getName()
{
  return this.name;
}

private void setSecret(String secret)
{
  this.secret = secret;
}
class child extends father
{
     private String secret;

    private void setSecret(String secret)
    {
        this.secret = secret;
    }
}

那麼在記憶體中,父類物件的指標指向父類物件資料區,子類的物件指標同時也是指向父類物件中的public資料,同時也是指向自己的資料區。即子類物件和父類物件存在記憶體區的交叉。並不是子類物件建立的過程將public或者protected資料copy到自己的指向區域,單獨獨立。所有隻要public或者protected資料在子類物件中修改了,那麼父類物件取出的資料也是修改之後的資料,因為本質上是同一個資料。

不用語言程式設計的區別的理解:
系統,不管是windows系統、Linux、還是Android;其對記憶體資料的分割槽、生命週期的管理和劃分都是近似的。那麼不同語言的程式設計最終生成的程式或者應用都是跑在這些系統上,那麼為什麼語言不同導致在系統上的記憶體分配,管理和生命週期不一樣呢?原因在於不同語言的程式設計(這裡不要把語言理解就是簡單的程式設計語法或者關鍵字不一樣,而是包含編譯器或者語言生成機器碼的環境工具,因為程式碼檔案最終要通過工具生成機器碼,編譯工具才是理解程式語言的核心)最終要告訴作業系統生成資料的區域,從而決定生命週期。同時也告訴作業系統對資料如何封裝,生成對應的封裝物件指標,然後根據資料結構查詢對應的成員。所以不同語言的程式設計在於最終生成機器碼的時候,生成的資料結構和資料存放區域。Java還包含告訴系統的資料回收演算法和異常輸出演算法等。