自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

談?wù)勎覍?duì)面向?qū)ο笠约邦?lèi)與對(duì)象的理解

開(kāi)發(fā) 開(kāi)發(fā)工具
對(duì)于剛接觸JAVA或者其他面向?qū)ο缶幊陶Z(yǔ)言的朋友們來(lái)說(shuō),可能一開(kāi)始都很難理解面向?qū)ο蟮母拍钜约邦?lèi)和對(duì)象的關(guān)系。筆者曾經(jīng)帶過(guò)一個(gè)短期培訓(xùn)班教授java入門(mén)基礎(chǔ),在最后結(jié)束課程的時(shí)候,還有很多同學(xué)不太理解面向?qū)ο蟮乃季S以及類(lèi)與對(duì)象的意義。

[[173166]]

文章最初發(fā)表于我的個(gè)人博客非典型性程序猿

對(duì)于剛接觸JAVA或者其他面向?qū)ο缶幊陶Z(yǔ)言的朋友們來(lái)說(shuō),可能一開(kāi)始都很難理解面向?qū)ο蟮母拍钜约邦?lèi)和對(duì)象的關(guān)系。筆者曾經(jīng)帶過(guò)一個(gè)短期培訓(xùn)班教授java入門(mén)基礎(chǔ),在最后結(jié)束課程的時(shí)候,還有很多同學(xué)不太理解面向?qū)ο蟮乃季S以及類(lèi)與對(duì)象的意義。這幾天有空,就想著整理整理自己的思路,談?wù)勛约簩?duì)面向?qū)ο笠约邦?lèi)與對(duì)象的理解。

面向?qū)ο?/strong>

首先,一言不和先百度,得到如下定義:

一切事物皆對(duì)象,通過(guò)面向?qū)ο蟮姆绞?,將現(xiàn)實(shí)世界的事物抽象成對(duì)象,現(xiàn)實(shí)世界中的關(guān)系抽象成類(lèi)、繼承,幫助人們實(shí)現(xiàn)對(duì)現(xiàn)實(shí)世界的抽象與數(shù)字建模。

我們知道,編寫(xiě)程序的目的是為了解決現(xiàn)實(shí)生活中的問(wèn)題,編程的思維方式也應(yīng)該貼近現(xiàn)實(shí)生活的思維方式。面向?qū)ο蟮木幊谭绞骄褪菫榱藢?shí)現(xiàn)上述目的二出現(xiàn)的。它使得編程工作更直觀,更易理解。需要注意的是這里說(shuō)的編程不光是coding還包括了設(shè)計(jì)的過(guò)程也是面向?qū)ο蟮?/p>

為什么說(shuō)面向?qū)ο蟾N近實(shí)際生活

想象一下,當(dāng)我們向別人描述一樣事物時(shí),我們都是怎么說(shuō)的?"它有像鴨子一樣的嘴巴","它有4條退","爪子里還有蹼","它是哺乳動(dòng)物但卻是卵生"。

這種HAS A 和 IS A的表達(dá)方式往往可以簡(jiǎn)單而高效的描述一樣事物。HAS A描述事物的屬性或行為,IS A 則說(shuō)明了事物的類(lèi)屬。

當(dāng)我們把這一系列的屬性組合起來(lái)便得到的鴨嘴獸這一類(lèi),同時(shí)哺乳動(dòng)物一詞簡(jiǎn)單精煉的表面了所有哺乳動(dòng)物的特性而不用一一列出,這是繼承特性的體現(xiàn),同時(shí)卵生又是多態(tài)的體現(xiàn)。

這就是面向?qū)ο蟮乃季S特點(diǎn),抽取(抽象)有用的屬性和行為(拋棄哪些無(wú)需關(guān)系的)組織(封裝)成一個(gè)類(lèi)。這個(gè)過(guò)程中你也許會(huì)發(fā)現(xiàn)很多屬性或方法是和另一個(gè)類(lèi)相同的,那么你就可以采用繼承的方式避免重復(fù)(當(dāng)然這個(gè)過(guò)程也有可能是,當(dāng)你設(shè)計(jì)完一個(gè)個(gè)類(lèi)后,才發(fā)現(xiàn)他們有共同點(diǎn),然后再抽取出基類(lèi))。更重要的是,繼承是可以不原樣照搬的,我們可以通過(guò)重載實(shí)現(xiàn)相同行為或?qū)傩缘奶赜袑?shí)現(xiàn)方式,這種特點(diǎn)稱(chēng)之為多態(tài),例如同樣的生產(chǎn)行為,實(shí)現(xiàn)方式由胎生變?yōu)槁焉?。?qǐng)大聲念出,并牢牢記住面向?qū)ο蟮乃膫€(gè)特征:

  • 抽象
  • 封裝
  • 繼承
  • 多態(tài)

與早期結(jié)構(gòu)化編程相比

早期結(jié)構(gòu)化編程是面向過(guò)程的(功能),換句話說(shuō)程序是由功能的集合組成,而調(diào)用者是作為功能的參數(shù)傳入的。而在面向?qū)ο蟮某绦蛑校瑢?duì)象是主體,程序是由對(duì)象的集合組成。一個(gè)對(duì)象中包含一系列符合設(shè)計(jì)的功能供其他對(duì)象調(diào)用。這么說(shuō)可能還是比較抽象,

例如當(dāng)我們?cè)O(shè)計(jì)一個(gè)五子棋游戲時(shí),面向過(guò)程的設(shè)計(jì)思路就是首先分析問(wèn)題的步驟: 

1、開(kāi)始游戲,2、黑子先走,3、繪制畫(huà)面,4、判斷輸贏,5、輪到白子,6、繪制畫(huà)面,7、判斷輸贏,8、返回步驟2,9、輸出最后結(jié)果。

把上面每個(gè)步驟用分別的函數(shù)來(lái)實(shí)現(xiàn),問(wèn)題就解決了。

而面向?qū)ο蟮脑O(shè)計(jì)則是從另外的思路來(lái)解決問(wèn)題。整個(gè)五子棋可以分為:

1、黑白雙方,這兩方的行為是一模一樣的,2、棋盤(pán)系統(tǒng),負(fù)責(zé)繪制畫(huà)面,3、規(guī)則系統(tǒng),負(fù)責(zé)判定諸如犯規(guī)、輸贏等。

第一類(lèi)對(duì)象(玩家對(duì)象)負(fù)責(zé)接受用戶(hù)輸入,并告知第二類(lèi)對(duì)象(棋盤(pán)對(duì)象)棋子布局的變化,棋盤(pán)對(duì)象接收到了棋子的變化就要負(fù)責(zé)在屏幕上面顯示出這種變化,同時(shí)利用第三類(lèi)對(duì)象(規(guī)則系統(tǒng))來(lái)對(duì)棋局進(jìn)行判定。

(以上例子來(lái)自國(guó)內(nèi)著名問(wèn)答社區(qū))

隨便寫(xiě)點(diǎn)代碼,大家看看就好,不要太認(rèn)真....

  1. /** 
  2. 玩家類(lèi) 
  3. **/ 
  4. public class Player { 
  5.     String name;       //棋手名稱(chēng) 
  6.     boolean isFirst;  //是否先手 
  7.     int color_flag;  //代表顏色  0-白 1-黑 
  8.     Table table;//棋盤(pán)對(duì)象 
  9.      
  10.     public Player(String name,boolean isFirst;int color_flag){ 
  11.              this.name=name
  12.              this.isFirst=isFirst; 
  13.              this.color_flag=color_flag; 
  14.       } 
  15.     
  16.     /** 
  17.     下棋,x,y為落子坐標(biāo) 
  18.     **/ 
  19.     public void play(int x,int y) throws Exception{ 
  20.       if(this.table==null){ 
  21.          throw new IllegalArgumentException("玩家還未注冊(cè)到棋盤(pán)!"); 
  22.       } 
  23.       table.setNewPieces(x,y); 
  24.     } 
  25.      
  26.     public void setTable(Table table){ 
  27.        this.table=table
  28.     }  
  29. /** 
  30. 棋盤(pán)類(lèi) 
  31. **/ 
  32. public class Table
  33.   List<Player> playerList=new ArrayList<Player>(); 
  34.   Referee referee ; 
  35.   public Table(){ 
  36.    referee =new Referee(this); 
  37.   } 
  38.   /** 
  39.     注冊(cè)玩家 
  40.   **/ 
  41.   public void registPlayer(Player player) throws Exception { 
  42.       //檢測(cè)棋盤(pán)中的玩家是否已滿,先手玩家和玩家選色是否沖突。 
  43.       ....... 
  44.      playerList.add(player); 
  45.      player.setTable(this); 
  46.   } 
  47.  
  48.    /** 
  49.     落子 
  50.    **/ 
  51.  
  52.    public void setNewPieces(int x , int y){ 
  53.           //重新繪制棋盤(pán) 
  54.           ...... 
  55.          //調(diào)用裁判對(duì)象,判斷結(jié)果 
  56.       if(referee.isEnd){ 
  57.           End(); 
  58.         } 
  59.    } 
  60.  
  61.    public void End(){ 
  62.       ....... 
  63.   } 
  64. /** 
  65. 裁判類(lèi) 
  66. **/ 
  67. public class Referee(){ 
  68.   Table table; 
  69.   public Referee(Table table){ 
  70.     this.table=table
  71.  } 
  72.  
  73.    public boolen isEnd(){ 
  74.       //判斷輸贏 
  75.       .... 
  76.     return false;  
  77.    } 
  78.  

然而事實(shí)上,通過(guò)上述示例代碼,我們不難發(fā)現(xiàn),即使我們使用面向?qū)ο蟮姆绞?,上面例子里面向過(guò)程中提到的幾個(gè)下棋過(guò)程我們還是都實(shí)現(xiàn)了的,只不過(guò)程被封裝到了類(lèi)的方法中。所以說(shuō)其實(shí)面向?qū)ο蠛兔嫦蜻^(guò)程并不是編程的區(qū)別(需要實(shí)現(xiàn)的業(yè)務(wù)邏輯的量不會(huì)產(chǎn)生變化),而是設(shè)計(jì)的區(qū)別!

類(lèi)與對(duì)象

類(lèi)是抽象的,而對(duì)象是具體的

如何理解上面的話呢? 例如鴨嘴獸是類(lèi)型,具體的鴨嘴獸A、鴨嘴獸B就是對(duì)象了。在JAVA中對(duì)象是通過(guò)new關(guān)鍵字聲明的。 再例如,《紅色警戒》中美國(guó)大兵是一類(lèi)兵種,點(diǎn)擊制造后從兵營(yíng)里出來(lái)的那個(gè)會(huì)開(kāi)槍的家伙就是對(duì)象了:

類(lèi)的定義就是一個(gè)模板,它描述的一類(lèi)對(duì)象的屬性與行為。類(lèi)往往是抽象的、沒(méi)有實(shí)體的。哺乳動(dòng)物是類(lèi)的概念,是抽象的,現(xiàn)實(shí)中沒(méi)有哺乳動(dòng)物這一實(shí)體,只有具體的如老虎,獅子等。編程工作中套用這一思維模式,我們將程序中的實(shí)例抽象為類(lèi),例如一個(gè)系統(tǒng)中的用戶(hù)有張三、李四我們會(huì)把他們抽象為Person類(lèi),或者稱(chēng)之為一個(gè)名為Person的數(shù)據(jù)類(lèi)型。

對(duì)象則是根據(jù)所屬類(lèi)模板創(chuàng)造出來(lái)的實(shí)實(shí)在在的事物。在程序中我將這個(gè)實(shí)實(shí)在在的事物稱(chēng)之為實(shí)例,我們?yōu)樗膶傩再x上特定的值,讓它成為張三或者李四。在內(nèi)存里來(lái)說(shuō),對(duì)象是表示的就是具體數(shù)據(jù)。

前面說(shuō)的都是概念性的東西,下面我們說(shuō)說(shuō)實(shí)際的運(yùn)用過(guò)程中的理解。

從數(shù)據(jù)類(lèi)型來(lái)說(shuō)

以java為例,數(shù)據(jù)類(lèi)型分為基本數(shù)據(jù)類(lèi)型和引用數(shù)據(jù)類(lèi)型。

基本數(shù)據(jù)類(lèi)型就是byte,short,int,long,double,char,boolean;其它的,需要用到new關(guān)鍵字來(lái)賦值的都是引用數(shù)據(jù)類(lèi)型。 類(lèi)與對(duì)象指的便是引用數(shù)據(jù)的類(lèi)型與其值(這里指的類(lèi)不光是class,還包括接口、數(shù)組、枚舉、注解)。 而引用指的是內(nèi)存地址的引用,關(guān)于這點(diǎn)在后面說(shuō)的內(nèi)存時(shí)會(huì)細(xì)說(shuō)。

看下面的代碼:

  1. int a =1; 
  2.  
  3. Person b=new Person();  

a 和 b 都是本身無(wú)意義的變量名。需要關(guān)注的是:a的類(lèi)型是基本數(shù)據(jù)類(lèi)型int值為1,而b的類(lèi)型是Person屬于引用類(lèi)型,其引用的是new Person()這個(gè)對(duì)象。我們往往會(huì)說(shuō)對(duì)象xx,比如這里的對(duì)象b。但實(shí)際上b只是對(duì)象的引用,真正的對(duì)象是后面的new Person()!

需要注意的是String也是引用數(shù)據(jù)類(lèi)型,只不過(guò)因?yàn)槭褂寐史浅8?,所以?duì)于String,jvm支持其可 以像基本數(shù)據(jù)類(lèi)型一樣使用:String a = "abc"; 同等于 String a = new String("abc");

總之呢,簡(jiǎn)單來(lái)說(shuō)類(lèi)指的的引用數(shù)據(jù)的類(lèi)型,對(duì)象是具體賦的值。為了更深入理解,我們下面需要解釋下這個(gè)引用是如何體現(xiàn)的。

什么是引用(從內(nèi)存來(lái)說(shuō))

要深入理解什么是類(lèi),什么是對(duì)象,什么又是引用,就離不開(kāi)說(shuō)說(shuō)java的內(nèi)存使用方式。

在java中內(nèi)存被大致劃分為棧(stack)與堆(heap) (之所以是大致,是因?yàn)檫€包括其它幾部分就不在這細(xì)說(shuō))。

關(guān)于什么是棧與堆在這就不細(xì)說(shuō),有空我再整理一篇文章詳細(xì)說(shuō)明。

在這里我們只說(shuō)一點(diǎn):java中,基本數(shù)據(jù)類(lèi)型以及對(duì)象的引用都保存在棧(stack),而對(duì)象則保存在堆(heap)中,例如當(dāng)如下代碼:

  1. int a=1; 
  2.  
  3. Person p;  

內(nèi)存中的狀態(tài)大致如下:

int a = 1 是直接在棧中開(kāi)辟空間,而對(duì)于未進(jìn)行實(shí)例化的Person p因?yàn)闆](méi)有有效的內(nèi)存地址引用它的值是null。而當(dāng)代碼進(jìn)行如下修改時(shí):

  1. int a =1 ; 
  2.  
  3. Person p = new Person();  

內(nèi)存中的狀態(tài)大致如下:

 

 


Person p=new Person();使得p的值=0x8da23也就是對(duì)象new Person();在堆中的地址。所以,到這里后就不難理解之前說(shuō)的對(duì)象的引用了,所謂引用其實(shí)就是堆內(nèi)存地址的引用。 

總結(jié)

隨著計(jì)算機(jī)技術(shù)的不斷提高,現(xiàn)在計(jì)算機(jī)不單單是用來(lái)解決運(yùn)算問(wèn)題,而是被用于解決越來(lái)越貼近現(xiàn)實(shí)生活的復(fù)雜問(wèn)題。面向?qū)ο缶褪沁@一發(fā)展進(jìn)程的產(chǎn)物,它使得編程工作更貼近人的思維方式,從而大大提升編程效率。我們必須明白的是面向?qū)ο蟛⒉皇且环N編程方式,而是一種編程思維方式,這種思維方式涵蓋了分析,設(shè)計(jì),編碼等。在面向?qū)ο缶幊讨?,程序的基本單元是?duì)象,數(shù)據(jù)封裝在對(duì)象中。類(lèi)是對(duì)象模板,是預(yù)定義好的結(jié)構(gòu),所謂的實(shí)例化一個(gè)類(lèi),所指的就是將數(shù)據(jù)填入模板。

最后,本人文筆不是很好,有待提高。寫(xiě)文章和博客的最大目的是梳理自己的思路,其二是分享自己的想法,望大家多多吐槽,愿共同提高。

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2012-06-07 10:11:01

面向?qū)ο?/a>設(shè)計(jì)原則Java

2009-01-04 09:08:30

面向?qū)ο?/a>繼承接口

2024-01-03 13:38:00

C++面向?qū)ο缶幊?/a>OOP

2012-12-18 09:24:47

2023-10-25 13:42:19

Java面向?qū)ο?/a>

2013-06-07 10:55:10

2023-11-30 08:00:54

面向?qū)ο?/a>面向切面

2010-02-02 13:15:26

Python類(lèi)

2023-01-10 09:38:09

面向對(duì)象系統(tǒng)

2023-09-27 23:28:28

Python編程

2023-11-02 07:55:31

Python對(duì)象編程

2022-02-21 07:45:29

面向?qū)ο?/a>代碼依賴(lài)倒置

2010-06-13 10:01:48

面向?qū)ο蠹夹g(shù)與UML

2021-07-02 14:14:14

Python對(duì)象設(shè)計(jì)

2021-07-16 10:23:47

Python設(shè)計(jì)對(duì)象

2012-06-12 14:23:02

面向?qū)ο?/a>編程開(kāi)發(fā)

2013-01-10 10:05:29

編程面向?qū)ο缶幊?/a>

2009-01-16 08:52:26

面向?qū)ο?/a>OOP編程

2010-07-08 10:47:42

UML面向?qū)ο?/a>

2010-07-20 09:13:55

Perl面向?qū)ο缶幊?/a>
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)