Java筆記系列(基於馬士兵的課堂)(1)-面向對象

1.    面向對象的編程設計思想(第三章內容)


區別於面向過程的設計思想

           


面向對象,封裝過程在對象的內部,合適的方法應該出現在合適的類裏面,(張三的名字讓張三寫最合適,讓李四寫並不合適)讓對象更瞭解自己的內部,調用對象來調用方法。首先考慮作用域中的對象,而不是考慮通過過程達到,再考慮對象,類應該有怎樣的屬性和方法,最後考慮作用域中對象與對象之間的關係,類與類之間的關係。

對象與類的關係

本質是面向類的編程,對象用計算機語言對問題的描述,對象通過屬性(也可以叫成員變量)和方法來分別對應事物所具有的靜態屬性和動態屬性。

就像腦子中抽象的一種事物所具有的特點(一類事物的抽象,擁有靜態屬性,動態屬性來下定義,定義這個類)其中靜態屬性對應成員變量,動態屬性對應方法。瓶子

對象(也可以叫實例)這一類事物具體的某一種特徵的具體的某個東西叫做對象。某一個瓶子(誰誰的某個怎樣的瓶子)

類可以衍生出多個對象,類可以認爲是一個模板,其衍生出的對象應具有他的靜態,動態屬性。但由於對象的不同其在類中的特點都有,但取值不同,所以區別了每個對象,每個對象都有自己的屬性,區別於其他對象不同的屬性。

類與類之間的關係

對象與對象之間的關係

1,關係與關係(弱):關聯關係(最不緊密)常用:一個類的方法是另外一個類的對象

2,繼承關係(強):(一般和特殊)…是一種…說的通就是繼承關係(球類運動員是一種運動員,球類運動員從運動員中繼承,籃球運動員是一種球類運動員,籃球運動員又從球類運動員中繼承)這種關係很有可能派生出一個繼承樹,一個類可以從多個類中繼承,同時也可以被多個類繼承,從多個節點中(基本的),衍生出多個(特殊的),與c++中的多重繼承相關。

3,聚合關係(強):(整體和部分的關係)誰誰是誰誰的一部分,說通之後就是聚合關係。也可以細分爲聚集關係和組合關係,聚集關係往往成員之間是可以分開的(一個部分的。。也屬於別的整體),但組合關係中成員與整體之間往往是密不可分的(一個部分只屬於某個整體)。

4,實現關係(父類與子類之間的關係):去…,用車,用…車,怎樣去,繼承子類,通過某種方法實現叫實現關係。

5,多態:以後介紹。

對象和類的分析。(方法:找名詞)

例1:


分清名詞是類,還是方法。

旅行社,機票,旅客,賬簿,目錄是類。

機票所具有的屬性:價格,時間,班次
……機票所具有的方法:作廢,顯示價格,顯示航班時間。

方法與所需目的有關才需要封裝在此類裏,否則並不需要封裝。

Java與面向對象

必須先定義類纔能有對象,對象是java的核心。

對象是靜態屬性(成員變量)動態屬性(方法)的封裝體。

就像寫程序時,寫public class 在這個class中寫成員變量,和方法。

這個成員變量(屬性)應該有他的類型。方法應該有返回值,也可以沒有返回值。

定義好類之後,開始做一個類的對象出來,類名 對象名 new 類名

J2sdk本身提供了許多類供編程人員使用,編程人員本身也可以定義自己的類(string,system)

爲什麼使用面向對象

Reusebility可重複使用性,屬性方法的複用(同時),extensibility可擴展性,可維護性…比面向過程高級,還有更高級的—面向組件的編程,component-orinted,向更高級的抽象(所有語言可以互相訪問)

Java中的面向對象與內存

 

6,         class關鍵詞(用class定義一個類)

成員變量(屬性,class靜態屬性):聲明—初始化(賦值)—用值

成員變量與局部變量區別:成員變量可以是java中的任何一種數據類型(包括基本類型和引用類型),其可以不初始化(也就是賦值),其有默認初始化。注意class與class之間同名屬性,其實不一樣。

引用類型(一小塊內存指向一大塊內存,指針,調用):除了8種基本類型之外所有都是引用類型—String s;(佔兩塊內存,未初始化之前內存中裝的是空值—null,與基本變量佔一塊內存不同)

              S = newString(“hello world”);(new出來的東西<對象>在heap
(堆內存動態分配內存的當不用時,就是垃圾垃圾收集器會回收)裏)


所謂new就是在內存中命名一塊空間,所有的引用類型全部是指針

變量(對象)對class的引用就是指針,類是靜態的在代碼區裏,類的每個成員變量在每個類中都有不同的值(除了靜態變量)。方法只有一份,執行的時候才佔內存。

對象的創建和使用:

使用對象.成員變量(或來引用對象的成員變量)。

使用對象.方法

同一類的每個對象有不同的成員變量儲存空間。

同一類的每個對象共享該類的方法。

內存中類和對象的關係

    

局部變量c1,c2在steak裏,引用class c時用c1.i使其指向heap裏的new對象中的屬性中的i。

構造函數(構造方法)

New + 構造方法  創建一個新的方法

必須和class名相同,不能有任何的返回值,不能寫void

方法調用完成之後,佔內存中所有局部變量佔用內存消失(局部變量消失),對象不會消失(留在heap裏),當沒有定義構造函數時,編譯器爲類自動添加

類名(){}的構造函數(空的構造方法,默認自定義初值)

構造方法出現的問題:

加入void 構造方法變成普通方法,構造方法沒有返回值

普通方法調用:引用名.方法名(穿值)

構造方法:類名 對象名=new 方法名();

約定俗成:

Class名大寫,變量名方法名首字母小寫,運用駝峯標示:如果名字由好幾個單詞構成,除了第一個詞之外,其他的詞都應該大寫。

沒有任何引用指向堆內存中的內存,垃圾收集器會收集它。

方法的重載

一個類中可以定義多個名字相同的方法,參數(類型)不同,根據參數輸入類型可以調用不同的方法。重載與重名不同,儘管可能返回值有無不同但只要輸入參數類型相同,方法名字相同,就是重名而並非重載。除了普通的方法以外,構造方法也可以構成重載。

對象的創建和使用

必須使用new關鍵字來穿件對象

對象.用成員變量或來引用對象的成員變量

使用對象引用.方法來調用對象的方法

同一類的每個對象有不同的成員變量儲存空間

同一類的每個對象共享該類的方法

非靜態的方法是針對每個對象進行調用(在沒有static的情況下)

This一般出現在方法中,當對象進行使用時才決定this指的是誰,此前不一定,用於避免重名問題,此後this永遠代表對象本身(在堆內存中),此後進行的一系列運算都是對象的值和變量類型。

Staticstatic聲明的成員變量爲靜態成員變量,他是該類的成員變量,第一次使用時被初始化,對於該類的所有對象static只有一份(不向普通《非靜態》成員變量,每個對象都有一份)。在data內存中一直存在無論是否有對象,沒有對象也可以訪問這個變量,用class名.靜態變量名(注意字符串常量也在data中)與常量不同該靜態變量可以改變

靜態變量可以用於記對象數(基礎類型不存在引用只有一塊內存

       Static聲明的所有方法爲靜態方法,靜態方法中只能引用的東西。

Package和import:爲了避免類的重名衝突。給包起名的方法:約定俗成—把公司的域名倒過來。(如com.bjsxt.java140)class必須位於正確目錄下,如果想在另外一個類中使用該類,要寫全這個名字。<該類源代碼可能會產生影響>,

Import 域名(包裹).類名(或者*,其中的所有類都引進)

(提供類的包裹在java jrelib 運行時《rt》中)Java.lang提供java語言核心類如String,math,integer,System,thread.

Java.awat 包含了抽象窗口工具集,用來構建和管理應用程序的圖形用戶界面(gui)

Java.applet 包含了applet運行所需要的類

Java.net包含執行與網絡想相關輸出的類。

Java.io包含提供多種輸入輸出功能的類

Java.util包含一些實用工具,如定義系統特性,適用於日期日曆相關的函數。

Jar -cvf用命令提示符可以生成jar包。

Classpath中設置jar包的位置設置進去就可以打開其中的所有的class文件。

繼承和權限控制:

Public關鍵字,訪問控制符,權限修飾符(private,default,protected,public)

繼承:類的繼承,extends關鍵字實現繼承機制,通過繼承子類擁有了基類(superclass)所有的成員變量和方法,java只允許單繼承不允許多繼承(只有一個爸爸),多重繼承應有意義,多重接口可以解決。

繼承在堆內存中顯示爲(子類中套有父類對象,以及類對象所有的成員變量),

所以子類比父類大,子類對象包含父類對象

訪問控制通過訪問修飾符來完成,訪問修飾符可以修飾成員變量,成員方法

可以顯示class名

Private (私有的)最嚴格的權限修飾符:只有在該class裏可以訪問,在其他class中無法訪問

Default(默認權限,包權限):被修飾對象前無訪問修飾符認爲是default修飾,

同一個包裏的其他類可以訪問該方法或者成員變量

Public:在所有位置都可以訪問。

Protected(受一定保護):除了類內部,同包,子類<子類不一定同包>也可以訪問。

與private不同,子類索然繼承值,但不能訪問。

對於class的權限修飾只能用public或者default

      在繼承時,子類必須重寫父類的構造方法

重寫方法不能使用比父類更嚴格的權限。

Super關鍵字,super來引用基類的對象,this是對當前的引用(指向當前對象),super是對當前對象中父類的的對象進行引用(指向當前對象中的父類對象)。

繼承中的構造方法:

子類可以在自己的構造方法中使用super調用其父類的構造方法,用this調用本類的其他的構造方法。Super (參數);調用父類構造方法。This(參數);調用本類的構造方法。若調用了父類的構造方法,一定寫在子類構造方法的第一行。

而且若有構造方法一定調用父類構造方法,若不調用,自動默認調用父類空值構造方法。

如果子類的構造方法沒有調用父類的構造方法,系統默認調用父類構造方法中沒有參數的構造方法。若不滿足上述條件,則編譯出錯。

在new某個類的對象時,自動使用該類的構造方法。

具體見person package

Jdk提供的類——object

object:http://docs.oracle.com/javase/1.5.0/docs/api/index.html

object類中的常用方法

java由於不可以多繼承,java提供了一個根基類,所有的類都要從這個類中繼承

這個類就是object類。

Public class Person{}=public class Person extends object{}它是classroot。

object類中的常用方法之toString() 方法

返回值:String(代表對象的字符串)

描述當前信息的有關信息

在進行String類型與其他類型數據進行連接時自動調用該對象的toString()方法

轉換非String類型變量變爲String類型

toString 方法每個類都應該重寫,注意返回值是String類型,默認toString返回值前面是類名後面是該類的阿西編碼(可以找到類位置的16進制碼)。

Hashcode(hashcodes table根據hashcode編碼表可以在內存中找到某個對象

Object之 equals方法

Equals用來比較對象所包含的內容是否相同(若簡單地比較路徑<引用>)

兩個對象首先不能爲空,當兩個對象都指向同一個對象,x==y纔會返回true。

所以Equals方法也應該重寫。重寫時勿忘加static讓其可以使用。

Jdk中date,string等類已經重寫了equals方法(object.equals())。

Instanceof可以去對象的類型,從而比較是否相同或者輸出。

對象轉型(casting

分爲兩種類型——向上轉型,向下轉型(與int轉short等相似)


一個父類的引用型變量可一指向其子類對象。


注意若父類類型轉爲子類類型(父類引用指向子類對象),只能訪問父類的屬性。比如animal類型a轉換爲dog——a=new dog(m,n),此時他變成了一隻狗,但系統會認爲他只是一隻普通的animal。可以進行強制轉換。

Dog d1=(dog)a;d1=a;


面向對象最核心機制:動態綁定(多態)(遲綁定)


在執行期間,而非編譯期間,判斷所引用對象的實際類型,來進行方法的引用。

運行之後是根據實際來判定方法調用,而非引用類型。動態綁定指的是,實際綁定的(new的是誰)用的就是誰的方法,而非簡單的引用方法,所以叫動態綁定。

最核心內存分析:(見test4)<注意不能隨便傳值>

若重寫了父類方法,在new對象時(子類套父類),在父類的內存裏就有一個指針指向子類重寫的方法。從而達到了空前的可擴展性。

多態的三個條件,1,要有繼承2,要有重寫3,父類引用指向子類對象(三個條件一旦滿足)

實際中如果對某個對象引用父類方法,實際是哪類對象就引用那類的方法,而非父類的方法。

遊戲物體的多態包裝:

如飛機大戰遊戲。將子彈和敵方飛機定義爲對象。將顯示其圖形的方法,定義爲若這個對象是子彈則畫出子彈的圖形,如果是敵方飛機則定義爲敵方飛機的類型(當然敵方飛機也分爲好多種,可以構建其子類,敵方飛機1,敵方飛機2,敵方boss…)如果臨時再加入一個新的類型的敵人,這種情況,首先繼承敵人這個類,重寫,父類中的Draw方法,系統根據對象運行方法,這裏叫多態,給程序的可擴展性帶來了極大的好處。

抽象類

Abstract修飾類叫抽象類,修飾方法叫抽象方法。父類中由於多態,自己的方法只需要定義,不需要運行,但父類本身並不知道自己的子類如何定義。

只有定義沒有實現,叫抽象方法。當一個類含有抽象方法時,這個類也得定義爲抽象類,abstractclass 類名。但此時不能再定義一個對象爲這個類的對象,而且子類必須對這個抽象類進行方法重寫。 此時這個抽象類必須被繼承,且這個子類若也爲抽象,一定循環下去,找到一個非抽象的子類重寫這個方法。抽象類不能被實例化,抽象方法只要生命不需要實現。

Final關鍵字:  (只讀,不寫)

可以修飾變量,方法,類。Final的方法不能被重寫,final的變量爲常量(與static不同,static可以根據每個對象的屬性進行改變但,final不可以。),final的類不能被繼承。Final的形式參數在方法內部不能被改變(因爲要傳實參。)

如果傳一隻貓,這隻貓只能指向一個內存。(如public final class math不能被繼承或者重寫)

接口(面向對象的最後一個概念)

由於java不能用多繼承,只支持單繼承,所以產生接口,接口可以幫助我們。

接口(interface):接口是一種特殊的抽象類。其中所有的方法都是抽象方法,不需要實現的,其中所有的成員變量都是具有public,static,final屬性的。

定義它:

Public interface runner{

Publicstatic final int id=1;//藍色可以不寫,寫不寫前面的內容都是一樣

Public void start();

Public void run();

Public void stop();

}

爲什麼要定義其所有成員變量爲final:爲了修正c++中多繼承的易出錯問題(當多個父類對象擁有相同成員變量時)。<其實這個變量並不屬於這個類>

所有的方法都是abstract的所以,每個方法都不用考慮實現,只需考慮返回值(與子類有關),局部變量。

多個無關的類可以實現同一個接口,一個類可以實現多個無關的接口,與繼承類似,接口與實現存在多態性(父類與繼承也存在多態性<動態綁定>)

定義java類的格式    clss<name>[extends<superclass>][ implements <interface>]

 在子類中,這些未實現的方法必須全部被實現。

,  比如接口(painter singer)與類(student teacher)。如果singer a=new teacher();則只能調用singer的方法,和其中的成員變量,其他看不到,但也可以將其強制轉換。如teacher b=(teacher)a;

 接口與抽象類的不同主要在於成員變量,方法是否都是抽象方法。

 接口的進一步理解:

 interface Comparable

中寫了怎樣比較大小,什麼樣是大,什麼樣是小,這樣在子類比較時,不用每一種類型比較大小的時候都寫一個方法,無論怎樣的類型,都只需要一個算法實現,達到了可擴展性。

同時接口之間可以相互繼承,且不用實現父類接口。

兩個接口中有兩個名字相同的方法,一個子類同時實現這兩個接口,若這兩個方法的返回值相同,則重寫時系統默認這兩個方法被同一個方法重寫,若返回值不同則無解。(若輸入值不同則重寫可以認爲構成重載)

總結:內存分析很重要

對象和類,面向對象,class,new(引用,構造方法),方法重載,this,static,package&import,訪問修飾符(private 成員變量只能看不能用),繼承,重寫,final,Object toString,Object equals,對象轉型(向上轉型,向下轉型),多態(繼承,重寫,父類對象指向子類方法),abstract class,interface(implements)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章