=============類和對象 ====================== 類:類是同一類事物的總稱。 對象:現實世界中實實在在存在的事物。 類和對象的關係:類是封裝對象的屬性和行爲的載體,反過來說具有相同屬性和行爲的一類實體稱爲類。如鳥類有鴕鳥、大雁、麻雀等。鴕鳥、大雁、麻雀被稱爲鳥類的實體,即對象。 面向對象:對象所共有的功能和屬性進行抽像,成爲了類。客觀事物在人腦中的主觀反映。在程序裏類是創建對象的模板。 面向對象程序設計的特點:封裝性、繼承性、多態性。 類成員:成員變量(屬性)和成員方法(行爲)。 定義成員方法的格式:權限修飾符 返回值類型 方法名(參數類型 參數名) {方法體 return返回值} 成員方法需要返回值時使用關鍵字 return java中的對象 :對現實對象的抽象(獲得有用的,捨棄沒用的)。 存儲空間中的一塊數據區域,用於存數據。如:人(nama sex age) 屬性:實例變量(定義在類以內,方法之外) 1.默認的初值 2.實例變量的使用範圍至少是類以內 3.實例變量調用必須有對象,實例變量和局部變量重名,局部優先。 例: public class Test{ public static void main(String[] args){ //新建對象stu;stu存的是新建對象stu的地址。stu的專業術語:引用/對象變量/引用變量/實例變量 Student stu=new Student(); stu.name="tom"; //給對象stu的name屬性賦值。 }} class Student{ //用類聲明的數據(str)爲引用類型,如:Student str; //實例變量:定義在方法之外,類以內的,沒有static修飾的變量 //實例變量會有一個默認的初始值。初始值與變量定義時的類型有關。 //實例變量(成員變量)--->屬性。可通過新建對象的引用來訪問類的實例變量。如,stu.name; String name; int age; String sex; } 實例變量和局部變量的區別: 1,位置:局部變量定義在方法裏面。實例變量定義在類以內方法之外。 2,使用的範圍:局部變量只能在定義他的方法裏面使用,直接調用變量名就可以了。 實例變量至少可以在定義他的整個類內使用,使用時必須用對象去調用。只有跟對象一起實例變量纔有意義。 3,局部變量使用之前必須初始化。實例變量不需要賦初值,系統會給默認的初值。 4,局部變量在同一方法裏不能重名。局部變量和實例變量可以重名,在方法裏採用就近原則。 =================方法:============= 包括: 方法: 做什麼:方法的定義 修飾符 返回類型 方法名(參數列表) 異常 怎麼做:方法的實現 {******} 修飾符(如:public) 返回類型(如:int) 方法名/函數名(參數表--形參) 如: public void eat(String fish){ //eat(),吃的功能。 //怎麼做. } 使用實例方法時也需要用對象去調用。如:stu.eat("fish"); ======構造方法====== 功能:創建其所屬類型的一個新的對象。(構造方法無返回值類型) 語法格式: < modifiers修飾符> <class_name類名>([< argu_list>]) { [< statements>] 方法體 } 舉例: –class Person { int age; Person() { age = 18; } Person(inti) { age = i; } void setAge(inti) { age = i; } –} Java語言中,每個類都至少有一個構造方法; 如果類的定義者沒有顯式的定義任何構造方法,系統將自動提供一個默認的構造方法: –默認構造方法沒有參數 –默認構造方法沒有方法體 Java類中,一旦類的定義者顯式定義了一個或多個構造方法,系統將不在提供默認的構造方法;每個子類的構造方法裏都有一個父類的默認構造方法,即super(),注意:前提是父類沒有顯示的構造方法,當父類有一個或多個顯示構造方法時,子類的構造方法要想調用,必須在方法體第一行加上 super(參數類型)。 方法重載(overloading):編譯時多態。 在一個類的內部,方法名相同形參數不同的方法,對返回類型不要求,這種現象稱之爲重載; 編譯器會自動選擇使用的方法。體現了一個編譯時多態。 好處:對使用者屏蔽因爲參數不同造成方法間的差異。 找方法時如果沒有合適的,採取自動向上擴展原則。 調用時形參之間的區別一定要明確。 1. 形參的個數不同 2. 形參的類型不同 3. 形參的順序不同 4. 形參的名字相同 方法覆蓋(override):運行時多態。 1,發生在父類和子類之間 2,方法名相同,參數相同,返回類型相同 3,子類方法的訪問權限不能更嚴格,只能等於或更加寬鬆。 構造方法: 1,沒有返回類型,方法名必須和類同名。 2,構造方法不能手動調用,它只用在創建對象在時候,只出現在new之後。 只要構造方法被調用運行,就一定有對象產生。 3,在一個對象的生命週期裏,構造方法只能被調用一次。 4,類寫好後一定有構造方法, 如果程序沒有顯示的提供構造方法,JVM會提供一個默認的構造方法,public classname(){} 如果程序顯示提供,系統不再提供默認的 5,同一個類的多個構造方法一定重載。 6,創建對象的同時構造方法的代碼塊裏還可以寫需要運行的代碼,還可以給屬性(實例變量)賦值, 引用類型的屬性賦值就是用new創建對象,然後調用構造方法。如:Student stu=new Student(); 用new創建對象時JVM做的三件事: 如:Student stu=new Student(); 1,申請空間;(把值放到空間裏,再把空間的地址給引用變量。)----創建父類對象 2,初始化實例變量;沒顯示聲明值的話就用默認值。 3,執行構造方法, 因爲實例變量在創建對象的過程中被初始化,所以使用實例變量前必須創建對象(要用對象去調用),否則實例變量根本不存在 =====關鍵字:this======= 1,在普通方法裏,指代當前對象引用(哪個對象調用該方法,this就指向該對象) 2,this不能出現在靜態方法裏。 3,在構造方法裏,this用來指代本類的其他構造方法。在本類構造方法之間互相調用。如:this(形參); 使用時放在構造方法裏的第一行。 4,不能寫成死循環(不能遞歸調用) =====關鍵字:super======= (和this的用法類似) 1,調用父類的構造方法,在子類調用父類的構造方法必須出現在第一句,構造方法第一句可能出現的三種情況(調用父類的構造方法看子類構造方法的第一句)①super();②super(參數)注意傳遞的參數一定是實體,有值的。③this(),先在本類的構造方法間調用,再看調用那個構造方法的第一句是什麼 2,super訪問父類的變量和方法,及super代表父類的對象,super.name;super.setName(); 注意:this 和super關鍵字不能同時存在在方法體中。 ======參數傳遞======== 1,參數相當於局部變量 2,參數傳遞相當於賦值語句 3,基本類型數據傳遞的是本身的值,引用類型數據傳遞的是引用xx(Animal animal)(地址,對象變量本身的值) 面向對象的三大特性: 一,封裝(Encapsulation):一個系統以合理的粒度出現。 定義:封裝就是將客戶端不應看到的信息包裹起來。使內部執行對外部來看不一種不透明的、是一個黑箱,客戶端不 需要內部資源就能達到他的目的。(封裝是把過程和數據包圍起來,對數據的訪問只能通過已定義的界面。面向對象 計算始於這個基本概 念,即現實世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個受保護的接口訪問其他對象。) 1.事物的內部實現細節隱藏起來 2.對外提供一致的公共的接口――間接訪問隱藏數據 3.可維護性 訪問控制修飾符:public(公開的),protected(受保護的,1,本包內可見;2,其他包的子類可見) default(默認,本包內可見),private(私有的,類內部可見) 訪問控制修飾符 (可以範圍) (可修飾)下面的類(指外部類) private 本類 方法,屬性 default 本包 類,方法,屬性 protected 本包+子類 方法,屬性 public 到處可見 類,方法,屬性 1,屬性:隱藏所有屬性,用private。隱藏後屬性只能在類以內訪問 。程序可以根據需要提供get和set 2,方法(函數):該公開的公開,該私有的就私有。(視情況而定) 3,公開方法的功能,隱藏方法的實現細節。 二,繼承(inheritance):抽象出不變性。 從一般到特殊的關係,可以設計成繼承 特點:共性寫在父類裏面,特性寫在子類 所有類的總父類是Object (Object是類的祖先) 父類裏寫的是共性,子類裏寫的是特性。 父類中用private修飾的屬性和方法不能被子類繼承; 但是父類裏的屬性子類都有,如果子類有特殊屬性的話,就要在子類裏定義 且在創建該子類對象的時候初始化屬性(包括父類所有屬性和該子類所有屬性); 什麼樣的功能和屬性可以繼承到子類? 對於父類裏的屬性和方法,子類有權訪問的,我們稱爲可以繼承; 用new創建子類對象,JVM執行的過程:Dog d=new Dog(); 爲d申請空間。class Dog extends Animal{} (1)申請空間;(把值放到空間裏,再把空間的地址給引用變量。) (2)看本類構造方法的第一句 (3)默認的創建父類對象: 執行順序:子類(2)---> 父類(2-->3-->4-->5)---> 子類(4-->5), 新建一個對象空間只申請一次(該空間存放所有父類和子類)。) (4)初始化本類的實例變量(該類的所有屬性); (5)執行本類的構造方法,(構造方法只會在創建一個對象的時候被執行一次) (創建是先執行父類的構造方法,在執行子類的構造方法,訪問時先訪問子類自己的特殊屬性和方法再訪問父類的屬 性和方法) 用super調用父類被子類覆蓋的普通方法和遮蓋的屬性 , 指代的是在創建子類對象過程中,由JVM自動創建的那個父類,如:super.方法名()/屬性 用super調用父類的構造方法;必須出現在子類構造方法的第一句。如:super(形參); 1,在子類的構造方法裏如果沒有指明調用哪一個父類的構造方法(就是子類中沒有super(形參)語句;), JVM會默認調用父類的無參構造方法,跟本類構造方法的形參沒有關係。 2,顯示的寫super,JVM會根據參數調用相應的父類構造方法。 3,有this(形參),在本類的構造方法之間調用,看被調用的那個構造方法的第一行。 三,多態(polymorphism):多態只有方法多態,沒有屬性多態。 用父類類型屏蔽子類之間的差異 所有的子類對象都可以當父類對象來用,一個父類型的引用可能指向的是一個子類對象, 如:把狗(對象)看作動物(類型)。Animal a=new Dog(); 編譯看前面,運行看後面。 (編譯時類型) (運行時類型) 1,運行時對象不會改變(對象是客觀存在的),如:狗這個對象的屬性和方法是不會改變的。 2,對一個引用,只能調用編譯時類型裏的已知方法。 如:編譯器知道動物裏已有的屬性和方法,但不知道狗的屬性和方法。 3,運行時會根據運行時類型自動尋找覆蓋過的方法運行。 引用 instanceof 類名 instanceof是Java的一個二元操作符,和==,>,<是同一類東西。 由於它是由字母組成的,所以也是Java的保留關鍵字。 它的作用是測試它左邊的對象是否是它右邊的類的實例,返回boolean類型的數據。 //結果爲boolean值, 引用所指向的對象和類名類型是否一致(對象是否屬於類名類型) 類型的轉換:轉換編譯時類型 Sub su= (Sub) s; 子類型的引用向父類型轉換時,不需要強轉 父類型的引用向子類型轉換時,需要強轉 Animal a=new Cat(); Dog d=(Dog)a; // 類型轉換異常 引用 instanceof 類名 -----> boolean 引用所指向的對象和類名所代表的類型是否一致 a instanceof Animal -----> true a instanceof Cat----------> true a instanceof Dog----------->false Employee e=new Manager(); e instanceof Employee ------>true e instanceof Manager------> true 屬性沒有多態,屬性只看編譯時類型 編寫程序的順序: class 類名{ private屬性(有什麼) 無參的構造方法(public類名(){}) 有參的構造方法(作用:給屬性賦值) set和get(設置和獲得屬性) 業務方法(做什麼) } 一,修飾符:static static變量:如:static int index=2; 類的所有對象共同擁有的一個屬性;可以用類名直接訪問,又稱爲類變量, 類的所有對象共同擁有的一個變量;類第一次被加載時會初始化靜態變量 (也就是會先執行static修飾的變量); 跟類創建了多少對象無關;任何對象對靜態變量做的修改,其他對象看到的是修改後的值。 可以用作計數器,記錄類創建對象的個數, static變量在類加載的時候只會被初始化一次, static方法:如:public static void teach(){} 可以用類名直接去調用,不需要對象所以不能直接訪問(在沒有對象的情況下)實例變量, 在靜態方法裏不能出現this和super,類的所有對象共同擁有的一個方法;跟類創建了多少 對象無關。 在繼承裏,父類的靜態方法只能被子類的靜態方法覆蓋,且覆蓋以後沒有多態 (訪問的是父類的靜態方法); static初始化塊:如:class Teacher(){ static int index=4; static{ //static初始化塊 ......... } } 靜態初始化塊:用static修飾類裏面的一個獨立的代碼塊,類第一次被JVM加載的時候執行,只 被執行一次。 類加載:JVM在第一次使用一個類時,會到classpath所指定的路徑去找這個類所對應的字節碼文件, 並讀進JVM保存起來,這個過程稱之爲類加載,一個線程一個jvm。 二,final (最後的,最終的)final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承 final類:如:final class Animal{} 表示該類不能被繼承,意味着不能改變裏面的代碼; 對虛擬機的正常運行有重要作用的類通常用final修飾,如:String,System,Math ...等類 final方法:如:public final void sleep(){} 該方法不能被覆蓋(修改),但能被子類訪問。 final變量:如:final (static) int index=4; 該變量是常量能被繼承(訪問); final修飾的變量就是常量,通常和static一起連用,來聲明常量; final修飾引用類型數據,指的是引用(地址)不能變,但引用裏的數據不受限制。 final修飾的變量,只要在初始化的過程中就可以賦值。 實例變量:聲明的同時或構造方法裏賦值; 靜態變量:聲明的同時或在靜態代碼塊裏賦值; 三,abstract abstract類:如:abstract class Animal{} 抽象類,不能創建對象(如一些父類),但是可以聲明一個抽象類型的引用 (可以聲明父類類型子類對象,編譯時利用多態調用抽象方法)。 含有抽象方法的類一定是抽象類,但抽象類並不一定要有抽象方法; 抽象類一般是用來被繼承的;子類繼承自抽象類,就要實現裏面的抽象方法, 如果不想讓子類也是抽象類的話,必須實現父類裏面所有的抽象方法。 抽象類有構造方法,有父類,也遵循單繼承的規律。 abstract方法:如:public abstract void sleep(); 抽象方法,只有方法名的定義,沒有實現體(只定義了能做什麼,沒定義怎麼做),不能被調用, 用於被子類的方法覆蓋或重新實現。只能放在抽象類中。 好處:允許方法的定義和實現分開。 public protected default private static final abstract 可以: public static private static public final public static final 不可以:abstract final void eat(); private abstract void eat(); static abstract void eat(); abstract不能和final,private,static連用。 四,interface:是抽象類的變體,。在接口中,所有方法都是抽象的。如:interface M{ int num=3; void eat(); } 理解爲接口是一個特殊的抽象類,所以接口不能創建對象,且接口沒有構造方法, 但可以聲明一個接口類型的引用(m是接口類型實現類對象,如:M m=new N();) 接口存在的意義是被子類實現,如果不想讓子類也抽象, 就要實現接口裏面所有的抽象方法,實現過程中注意訪問權限; 用 implements 關鍵字實現接口,如:class N implements M{ public void eat(){...} } 接口裏面的常量默認都是public static final的; 接口裏面的方法默認都是public abstract的。 接口本身支持多繼承,繼承了父接口裏功能的定義,如,interface A extends B,C,D{} //A,B,C,D都是接口; 類可以同時繼承一個父類和實現接口(或多個接口)。 如:class AA extends BB implements CC,DD,EE{}//AA,BB 是類,CC,DD,EE是接口; 作用:1,用接口去實現多繼承,接口是對類的共性進行再次抽象,抽象出類的次要類型。 如:蜘蛛俠,擁有人和蜘蛛的屬性,但主要類型是人,次要類型(接口)是蜘蛛, 因爲接口是次要類型,所以在類關係裏不佔一個節點,不會破壞類層次關係的樹狀結構, 2,標準(保證弱耦合):一個接口就是一個標準(裏面的屬性不能改變,只定義了功能, 但沒有被實現), 接口將標準的制定者,標準的實現者以及標準的使用者分離開, 降低實現者和使用者的耦合。接口是java裏一種重要的降低耦合的工具; 接口可以屏蔽不同實現類的差異, 當底層的實現類更換後,不會對上層的使用者產生影響,體現在參數和返回值。 寫程序時,應該先寫實現者再寫使用者,如:Bank.java是實現者,View.java是使用者, 但是有了接口之後,就可以用接口回調的功能; 接口回調:先定義接口,然後寫使用者和實現者的順序隨便(一般是先寫使用者, 後寫實現者);利用參數把實現者傳給使用者(即:實現者是使用者的屬性), 使用者利用接口調用實現者相應的功能。 **接口和抽象類的區別1一個類可以implements多個接口,而只能extends一個抽象類 2,一個抽象類可以實現部分的方法,而接口都是抽象的方法和屬性 Object是Java裏所有類的直接或間接父類,Object類裏面的所有功能是所有java類共有的 1,JVM調用垃圾回收器回收不用的內存(沒有引用指向的對象)前運行finalize(),給JVM用的方法。 程序顯示的通知JVM回收沒用的內存(但不一定馬上就回收):System.gc();或 Runtime.getRuntime().gc(); 2,toString()返回對象的字符串表現形式,打印對象時,虛擬機會自動調用toString獲取對象的字符串表現格式, 如:System.out.println(str.toString()); ==System.out.println(str); 如果本類不提供(覆蓋)toString(),那麼使用的是Object類裏的相應方法,打印的就是地址。 如:public String toString(){ return "....."; } 3,基本類型時“==“判斷變量本身的值是否相等;引用類型時,判斷的是地址是否相等。 equals判斷的是對象內容是否相等。對於自己創建的類,應該覆蓋Object類的equals()方法; 否則使用的是Object類裏的equals()方法,比的是地址。 覆蓋方法如下: /***************************************************** public boolean equals(Object o){ if(o==null) return false; if(o==this) return true; if(!(o.getClass()==this.getClass())) return false; final Student s=(Student)o; return this.name.equals(s.name) && this.age==s.age ; //比較原則; } ******************************************************/ 覆蓋euqals()方法時遵循的原則: 自反性:a.quals(a); //true 對稱性:a.equals(b);<==> b.equals(a); //true 傳遞性:a.equals(b);//true b.equals(c); //true --->則:a.equals(c); //爲true 封裝類(Wrapper class): OverLoading時,基本類型時採用向上匹配原則, 如果沒有基本類型的話就向包裝類轉換,如果還沒有就讓這個基本類型在包裝類裏也採用向上匹配原則; 基本類型-轉換到-->包裝類 boolean----->Boolean int-------->Integer //Integer是引用類型, int-------->Ddouble //合法, 但Integer------>Double 非法 double------>Double ...... -------> ...... 任何類型----->Object 基本數據類型int可以向double自動擴展,但是包裝類型之間不能自動的相互轉換, 基本類型數據--->包裝類型 int i=3; Integer it=new Integer(i); //手動轉換;基本類型向包裝類型轉換。 int <----> Integer <----> String 轉換時String類型必須爲全數字字符串。如:"2515" 不能爲:"abc265","aec"...等 String str=”123”; int it=Integer,parseInt(str);把字符串轉換成數字。String str2=it+“”;把數字轉化成字符串 ==內部類============ 定義在其他代碼塊(類體或者方法體)裏的類稱爲內部類; 編譯後每一個內部類都會有自己的獨立的字節碼文件, 文件名:Outer$Inner.class-->內部類也可以有父類和實現接口。也可以有抽象方法。 根本位置和修飾符的不同分爲四種: 1,member inner class 成員內部類,當實例方法或變量一樣理解。 1)定義的位置:類以內,方法之外,沒有靜態修飾符(static)。 2)本身能定義的屬性和方法:只能定義非靜態的屬性和方法。 3)能直接訪問的什麼:能訪問外部類的所有靜態和非靜態的屬性或方法。 4)怎麼創建對象:在外部類內的方法內:Outer.Inner inner=new Outer().new Inner(); 在外部類外的類的方法內:Outer.Inner inner=new Outer().new Inner();或 在Outer類裏提供一個getInner()方法,返回內部類的對象,這樣在外部類外的類的方法內也可以用該成員內部類。 2,static inner class 靜態內部類(嵌套內部類),當靜態方法或變量一樣理解。 static只能修飾內部類,不能修飾外部類。 1)定義的位置:類以內,方法之外,有靜態修飾符(static)。一般寫在外部類的屬性下面。 2)本身能定義的屬性和方法:可以定義靜態和非靜態的屬性或方法。 3)能直接訪問的什麼:只能訪問外部類的靜態屬性和方法。 4)怎麼創建對象:在外部類內的方法裏: Outer.Inner inner=new Outer.Inner(); 在外部類外的類方法裏: Outer.Inner inner=new Outer.Inner(); 3,local inner class 局部內部類 當局部變量一樣理解。 1)定義的位置:方法裏面的類,前面不能用public或static修飾。 2)本身能定義的屬性和方法:只能定義非靜態的屬性和方法。 3)能直接訪問的什麼:能訪問方法內用final修飾的局部變量(不能與該類內的變量名相同)。 能訪問外部類的所有靜態和非靜態的屬性或方法。 4)怎麼創建對象:只能在方法內創建對象,如:Inner inner=new Inner(); 對象的作用範圍只在方法內。 4,annonymous inner class 匿名內部類 如: Teacher tc=new Teacher(){ 1)沒有名字的類,沒有構造方法。是一個特殊的局部內部類, public void teach(){...} 可以實現一個接口, 或者一個類, } 生命週期裏只能產生一個對象(tc),也就是說只能被一個對象(tc)調用, 2)除了沒有名字外,看匿名內部類所在的位置,他的定義和訪問將和成員內部類、靜態內部類、局部內部類一樣。 一般像局部內部類的定義和訪問比較多。 3)當試圖創建接口或者抽象類對象的時候,用匿名內部類。 表示類體的{...}緊跟在抽象實例(接口)之後,表示實現該抽象實例(接口)。 調用匿名內部類的方法只能用寫類時創建的那個對象(tc)。 作用:1,不破壞訪問權限的情況下,內部類可以使用外部類的私有成員變量和方法。 2,將接口公開,將實現類(實現公開的接口)作成內部類隱藏起來,強制要求使用者使用接口,強制降低偶合度。 3,Java通過接口和內部類兩種機制來實現多繼承。在類內部可以建立本類的實例,然後調用本類內的其他方法。
java 之 類和對象 筆記
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.