1. 程式人生 > >Java面向物件程式設計之類和物件

Java面向物件程式設計之類和物件

Java程式語言是一種面向物件的程式語言,其特性在於高度的抽象性。那麼,什麼是面向物件呢?面向物件和麵向過程有什麼區別呢?萬物可歸類,什麼是類呢?萬物皆物件,類和物件之間的聯絡是什麼?Java程式的執行需要jvm(Java虛擬機器)的支援,那麼,面向物件程式設計在計算機中怎麼進行記憶體分析;任何類都有自己的構造方法,構造方法和常見的方法體是一樣的嗎?

(一)面向物件和麵向過程
面向物件和麵向過程同為對軟體分析設計開發的一種思想,指導人們用不同的思想設計開發軟體。
1. 舉個栗子: 設計五子棋來理解面向過程與面向物件。 面向過程的設計思路就是首先分析問題的步驟:1、開始遊戲,2、黑子先走,3、繪製畫面,4、判斷輸贏,5、輪到白子,6、繪製畫面,7、判斷輸贏,8、返回步驟2,9、輸出最後結果。把上面每個步驟用不同的方法來實現。
面向物件的設計思路是抽象組成問題的類,整個五子棋可以分為1、黑白雙方,這兩方的行為是一模一樣的,2、棋盤系統,負責繪製畫面,3、規則系統,負責判定諸如犯規、輸贏等。第一類物件(玩家物件)負責接受使用者輸入,並告知第二類物件(棋盤物件)棋子佈局的變化,棋盤物件接收到了棋子的變化就要負責在螢幕上面顯示出這種變化,同時利用第三類物件(規則系統)來對棋局進行判定。
2. 面向過程(OO)

:面向過程程式是由不同的函式組成,最小的程式單元是函式,每個函式負責完成某一個功能,用於接受輸入資料,函式對輸入資料進行處理,然後輸出結果資料,整個軟體系統由許多函式組成,其中作為程式入口的函式稱之為主函式,主函式依次呼叫其他函式,普通函式之間可以相互呼叫,從而實現整個系統功能。當你拿到一個問題時,你分析這個問題 是第一步先做什麼,第二步再做什麼,分析出解決問題所需要的步驟,然後用函式把這些步驟一步一步實現。其特點在於適合簡單任務,無需協作。指導思想是:具體問題具體分析

                                       面向過程的程式=演算法+資料結構

3. 面向物件(OOP)

:是以功能來劃分問題,而不是步驟,以一種元件化的形式進行程式碼設計,對於某一類問題的解決,一種以物件為基礎,以事件或訊息來驅動物件執行處理的程式設計技術。它具有抽象性、封裝性、繼承性及多型性 。面向物件處理問題:將面對的問題抽象處理,以物件為中心封裝成不同的類,然後例項化不同的具體物件,利用具體的物件來描述在整個問題的解決中所起到的作用。指導思想是:透過現象看本質。

                                                     物件=演算法+資料結構
                                               面向物件的程式=N個物件+控制資訊

4. 二者聯絡

              1>都是解決問題的一種思維方式 
              2>簡單問題可以使用面向過程的程式設計思想
              3>複雜問題在巨集觀層面上使用面向物件程式設計,在微觀層面上使用面向過程程式設計。

5. 例項蛋炒飯和蓋澆飯
用面向過程的方法寫出來的程式是一份蛋炒飯,而用面向物件寫出來的程式是一份蓋澆飯。
蛋炒飯製作把米飯和雞蛋混在一起炒勻。蓋澆飯呢,則是把米飯和蓋菜分別做好,你如果要一份紅燒肉蓋飯呢,就給你澆一份紅燒肉;如果要一份青椒土豆蓋澆飯,就給澆一份青椒土豆絲。

蛋炒飯的好處就是入味均勻,吃起來香。如果恰巧你不愛吃雞蛋,只愛吃青菜的話,那隻能全部倒掉,重新做一份青菜炒飯了。蓋澆飯就沒這麼多麻煩,你只需要把上面的蓋菜撥掉,更換一份蓋菜就可以了。蓋澆飯的缺點是入味不均,可能沒有蛋炒飯那麼香。 那麼從飯館角度來講的話,做蓋澆飯顯然比蛋炒飯更有優勢,他可以組合出來任意多的組合,而且不會浪費。

蓋澆飯的好處就是”菜”“飯”分離,從而提高了製作蓋澆飯的靈活性。飯不滿意就換飯,菜不滿意換菜。用軟體工程的專業術語就是”可維護性“比較好,”飯” 和”菜”的耦合度比較低。蛋炒飯將”蛋”“飯”攪和在一起,想換”蛋”“飯”中任何一種都很困難,耦合度很高,以至於”可維護性”比較差。軟體工程追求的目標之一就是可維護性,可維護性主要表現在3個方面:可理解性、可測試性和可修改性。面向物件的好處之一就是顯著的改善了軟體系統的可維護性。

(二)類和物件
<1>類的定義
對所具有相同特徵實體的抽象。
在面向物件的程式設計語言中,類 是抽象的概念集合,表示的是一個共性的產物,類之中定義的是屬性和行為(方法) 。
類就是具備某些共同特徵的實體的集合,它是一種抽象的資料型別,
比如說動物就是一類事物,作為動物是一個類的定義,即為class。其屬性就是動物所具有的特性,比如說大小,形狀,等,行為即是指動物所具有的行為方式,行走,吃飯,睡覺等。

//定義類的格式
public class 類名{
        定義屬性: 類的特性,事物的基本特徵,可以通過變數來定義屬性,比如人的姓名
             private String    name    =  “張飛”;
           修飾符 資料型別 變數名 = 值;
定義方法: 類具有的行為   用來定義該事物的具體功能的。
    修飾符 返回值型別 方法名(引數列表){
                          
            }
      }

定義一個人的類:

class Person {     // 類名稱首字母大寫
    String name ;   //屬性
    int age ;
    public void tell() {        // 沒有static,方法、
             System.out.println("姓名:" + name + ",年齡:" + age) ;
     }
}

<2>物件的定義
物件就是一個真實世界中的實體,物件與實體是一一對應關係的,意思就是現實世界的每一個實體都是一個物件,所以物件是一個具體的概念,(類的具體化和例項化)
動物類為例,具體的某個動物,比如說貓,貓作為一個具體的物件,不僅具有動物類的所有屬性和行為,同時可以具有自己的特點。
在這裡插入圖片描述

屬性用來描述具體某個物件的特徵。比如小志身高180M,體重70KG,這裡身高、體重都是屬性。
面向物件的思想就是把一切都看成物件,而物件一般都由屬性+方法組成!

屬性屬於物件靜態的一面,用來形容物件的一些特性,方法屬於物件動態的一面,咱們舉一個例子,小明會跑,會說話,跑、說話這些行為就是物件的方法!所以為動態的一面, 我們把屬性和方法稱為這個物件的成員!

<3>類和物件的比較
類和物件的區別
  1,類是一個抽象的概念,它不存在於現實中的時間/空間裡,類只是為所有的物件定義了抽象的屬性與行為,類是對於一系列物件的抽象。就好像“Person(人)”這個類,它雖然可以包含很多個體,但它本身不存在於現實世界上。
  2,物件是類的一個具體。它是一個實實在在存在的東西。
  3,類是一個靜態的概念,類本身不攜帶任何資料。當沒有為類建立任何物件時,類本身不存在於記憶體空間中。
  4,物件是一個動態的概念。每一個物件都存在著有別於其它物件的屬於自己的獨特的屬性和行為。物件的屬性可以隨著它自己的行為而發生改變。  
類:具有同種屬性的物件稱為類,是個抽象的概念。比如“人”就是一類,期中有一些人名,比如小明、小紅、小玲等等這些都是物件,類就相當於一個模具,他定義了它所包含的全體物件的公共特徵和功能,物件就是類的一個例項化,小明就是人的一個例項化!我們在做程式的時候,經常要將一個變數例項化,就是這個原理!我們一般在做程式的時候一般都不用類名的,比如我們在叫小明的時候,不會喊“人,你幹嘛呢!”而是說的是“小明,你在幹嘛呢!”

(三)面向物件記憶體分析
Java虛擬機器的記憶體:棧stack,堆heap,方法區method area

  • 棧中儲存的是Java八種基本資料型別的變數(short, int, long, byte, double, float, char, boolean),引用資料型別的區域性變數,物件的引用變數(相當於物件例項或者陣列的名字)
    1>描述的是方法執行的記憶體模型,每個方法呼叫都會建立一個棧幀(儲存區域性變數,運算元方法入口等)
    2>jvm為每個執行緒建立一個棧(儲存模型類似於子彈夾),用於存放該執行緒執行方法的資訊(如實參)
    3>棧屬於執行緒私有,不能實現執行緒的共享
    4>棧的儲存模型:先進後出,後進先出,(類似於子彈夾)
    5>棧由系統自動分配,一個連續的記憶體空間。、
  • 堆的特點用來存放動態產生的資料,比如new出來的物件
    1>堆用來儲存建立好的物件和資料
    2>jvm只有一個堆,且被所有執行緒共享
    3>堆是一個不連續的儲存空間。
  • 方法區的特點
    1>jvm只有一個方法區,被所有執行緒共享
    2>方法去也是堆,常用來儲存常量相關的資訊。
    3>用來存放程式中不變或者唯一的內容。

在這裡插入圖片描述

舉例說明:

//車類
class Car{		//事物的公共屬性使用成員變數描述。
	String	name; //名字的屬性
 	String	color; //顏色屬性
 	int wheel;	//輪子數
 		//事物的公共行為使用函式描述。
	public void run(){
		System.out.println(name+"飛快的跑起來啦...");
	}
} 
class Demo1{
	public static void main(String[] args){	
		Car c1 = new Car(); 
		c1.name = "寶馬";
		Car c2 = new Car();
		c2.name = "大眾";
		c1 = c2; 
		System.out.println("名字:"+ c1.name);
	}
}

執行結果:名字:大眾
記憶體分析:
在這裡插入圖片描述

jvm以main函式作為程式入口:
1.先聲明瞭c1變數 分配在棧記憶體
2.new Car 在堆記憶體建立了一個車物件 看看Car有那些成員屬性,然後再給物件分配初始值,為name=null,color=null,wheel=0 (成員一旦建立,物件的成員變數也會馬上分配預設的初始值) 然後把地址0x97賦給了c1 c1就指向了車的這個物件。
3. c1.name就是c1拿著地址找到車的物件 然後把name改成" 寶馬 "
4.再聲明瞭c2變數 分配在棧記憶體
5.再new 一個 Car 在堆記憶體再建立了一個車物件 看看Car有那些成員屬性,然後再給物件分配初始值,為name=null,color=null,wheel=0 (成員一旦建立,物件的成員變數也會馬上分配預設的初始值) 然後把地址0x67賦給了c2 c2就指向了車的這個物件。
6. c2.name就是c2拿著地址找到車的物件 然後把name改成“ 大眾 ”
7. 把c2的持有地址賦給了c1 c1的地址原來是0x97 改為 0x67
8 c1拿著改後的地址去找地址為0x67的物件 輸出為0x67地址的物件中的屬性name.
所以結果為;大眾

java1記憶體分析:
Java記憶體分配全面淺析
java執行的詳細記憶體分析,精確到每一步!!!!
Java 記憶體分配全面淺析 ]

(四)構造方法

  用於物件的初始化

(1)通常用new關鍵字呼叫
(2)構造器有返回值,但不能定義返回值型別,且不能再構造器中使用returen返回一個值
(3)若沒有定義構造器,系統會自定義一個
(4)構造器必須和·類名一致
普通方法有返回型別,方法名小寫,不能和類名相同,如:void XX(){}  普通方法:代表物件可以幹什麼
Java中類的構造方法

總結: 面向物件和麵向過程是兩種不同的程式設計思想,面向物件利用事物的共性抽象成類,然後例項化以形成物件,從A到B,怎麼走,先抽象一個A類,抽象一個B類,然後抽象一個路徑類,設計每一個類的具體方法,例項化三個類即可。也就是透過現象看本質,面向過程的程式設計思想對待不同的問題有不同的解決方式,從A到B,怎麼走,第一步是什麼,第二步是什麼,等等,具體問題具體分析。類是一個高度抽象的思維,也即一類有共性的實物的抽象,物件是類的例項化,即類的具體某一個實際形象,任何問題都可以抽象成幾個類的集合, 通過設計類自己在整個問題中的方法,然後例項化類,通過類之間的關係來解決問題。jvm虛擬機器用來執行Java程式,對於程式進行記憶體分析時,通過mian函式作為程式的入口,在棧中分配記憶體,在堆中分配初始化成員屬性,儲存建立好的物件和資料。構造方法和普通方法一樣,用來表示物件可以做什麼,只不過,過早方法必須和類名相似,用於物件的初始化。