Java第二章----對象和類
從第一章到第二章整整隔了一個月的時間,這速度也是慢的無語了。因為這個月負責開發公司一個SaaS類型APP,忙的昏天暗地終於上線了,這才有時間寫個博客。本章還是以概念為主,有點枯燥重在理解。
第一節:對象
-
名詞解釋
- OOA-Object Oriented Analysis-面向對象分析
- OOD-Object Oriented Design-面向對象設計
- OOP-Object Oriented Programming-面向對象程序設計
-
面向對象基本特性
- 萬物皆可為對象:任何一件事物都可以表示為程序中的對象
- 程序是對象的集合:它們通過發送信息來告知彼此所需要做的
- 每個對象都有自己的或有其他對象所構成的存儲:如:對象中引用其他對象
- 每個對象都擁有其類型:每個對象都是某個類class的實例,這裏的類就是指類型
- 某一指定類型的所有對象都可以接受相同的信息:如:person對象擁有father和mother對象的所有性質
- 一句話總結就是:對象具有狀態行為和標識,內部數據即狀態-方法即行為-存在內存中的唯一地址即標識
-
面向對象三個特性
- 封裝(encapsulate):把客觀事物封裝成抽象的類,並且類中的屬性和方法有自己指定的訪問權限。隱藏具體細節,是調用者只能遵循自己定義的規則,方便權限控制
- private:成員變量和方法只能在類內被訪問,具有類可見性
-
default:成員變量和方法只能被同一個包裏的類訪問,具有包可見性
-
protected:可以被同一個包中的類訪問,被同一個項目中不同包中的子類訪問
-
public:可以被同一個項目中所有類訪問,具有項目可見性,這是最大的訪問權限
- private:成員變量和方法只能在類內被訪問,具有類可見性
- 繼承:指子類有父類所有的功能,並可以重寫或補充自己的方法
-
關鍵字:extends ,Java是單繼承關系所有對象的父類都是Object,多繼承容易使代碼混亂,單繼承使只有一個父類代碼邏輯更清晰如:它們都是相同的數據類型都有相同的方法功能且單繼承結構對垃圾回收機制實現變得容易的多。Java是單繼承多實現接口的結構。
-
重載(overloading):同一個類中有相同的方法名字不同的參數叫做方法重載
-
重寫(overriding):兩個類之間必須存在繼承關系,且子類重寫了父類中有的方法,包括方法名字參數返回值都相同,如果需要調用父類中方法須用super關鍵字調用
-
- 多態:指一個實現類在不同的情景下有不同的實現方式,即不同的類可以實現相同的接口來完成不同的任務,但我們可以通過相同的方式予以調用
-
條件:必須存在繼承關系,子類重寫父類的方法,向下轉型
- 轉化規則:子類轉換父類向上轉型可直接賦值,父類轉換子類向下轉型許強制類型轉換且無法調用子類特有方法
-
1 package com.fengzb.java002.object; 2 3 /** 4 * @Description 封裝 5 * @Author jxb 6 * @Date 2017-06-10 22:52:20 7 */ 8 public class Person { 9 10 /** 11 * 手 12 */ 13 private String hand; 14 15 /** 16 * 腳 17 */ 18 private String foot; 19 20 /** 21 * 頭 22 */ 23 private String head; 24 25 public String getHand() { 26 return hand; 27 } 28 29 public void setHand(String hand) { 30 this.hand = hand; 31 } 32 33 public String getFoot() { 34 return foot; 35 } 36 37 public void setFoot(String foot) { 38 this.foot = foot; 39 } 40 41 public String getHead() { 42 return head; 43 } 44 45 public void setHead(String head) { 46 this.head = head; 47 } 48 49 /** 50 * 無參構造方法 51 */ 52 public Person(){ 53 System.out.println("--jxb--Person--Person:我是Person無參構造方法"); 54 } 55 56 /** 57 * @Description private方法可以在同一個類中調用 58 * @Param 59 * @Author jxb 60 * @Date 2017-06-11 23:19:48 61 */ 62 private void isPerson() { 63 System.out.println("--jxb--Person--isPerson:" + "我是人"); 64 } 65 66 /** 67 * @Description 默認方法只有同一個包裏可用 68 * @Param 69 * @Author jxb 70 * @Date 2017-06-12 12:32:00 71 */ 72 void useHeadThinking() { 73 System.out.println("--jxb--Person--useHeadThinking:" + "人用頭想事情"); 74 } 75 76 /** 77 * @Description protected方法同一個包可見,同一個項目不同包的子類可見 78 * @Param 79 * @Author jxb 80 * @Date 2017-06-12 12:36:06 81 */ 82 protected void useFootWalk() { 83 System.out.println("--jxb--Person--useFootWalk:" + "人用腳走路!"); 84 } 85 86 /** 87 * @Description public方法可以同項目中所有類訪問 88 * @Param 89 * @Author jxb 90 * @Date 2017-06-11 23:17:15 91 */ 92 public void useHandEat() { 93 System.out.println("--jxb--Person--useHandEat:" + "人用手吃飯!"); 94 } 95 96 /** 97 * @Description private方法可以在同一個類中調用 98 * @Param 99 * @Author jxb 100 * @Date 2017-06-11 23:19:48 101 */ 102 public void personDetail() { 103 System.out.println("--jxb--Person--personDetail:" + "我是人類"); 104 } 105 106 }
Person -
1 package com.fengzb.java002.object; 2 3 /** 4 * @Description 繼承 5 * @Author jxb 6 * @Date 2017-06-12 12:25:53 7 */ 8 public class Mother extends Person { 9 /** 10 * 姓名 11 */ 12 private String name; 13 14 /** 15 * 年齡 16 */ 17 private int age; 18 19 /** 20 * 性別 21 */ 22 private String sex; 23 24 public String getName() { 25 return name; 26 } 27 28 public void setName(String name) { 29 this.name = name; 30 } 31 32 public int getAge() { 33 return age; 34 } 35 36 public void setAge(int age) { 37 this.age = age; 38 } 39 40 public String getSex() { 41 return sex; 42 } 43 44 public void setSex(String sex) { 45 this.sex = sex; 46 } 47 48 /** 49 * @Description 50 * @Param 51 * @Author jxb 52 * @Date 2017-06-11 23:17:15 53 */ 54 public void useHandEat() { 55 System.out.println("--jxb--Person--useHandEat:" + "wbb用手吃飯!"); 56 } 57 58 /** 59 * @Description 60 * @Param 61 * @Author jxb 62 * @Date 2017-06-11 23:17:15 63 */ 64 public void motherDetail() { 65 System.out.println("--jxb--Father--motherDetail:" + this.name + "-" + this.getAge() + "-" + this.getAge()); 66 } 67 68 }
Mother
-
- 封裝(encapsulate):把客觀事物封裝成抽象的類,並且類中的屬性和方法有自己指定的訪問權限。隱藏具體細節,是調用者只能遵循自己定義的規則,方便權限控制
-
對象的生命周期
- 對象在堆(heap)的內存池中動態的創建,這種方式只有運行時才能知道有多少對象需要被創建,他們的生命周期如何,以及它們的具體類型。
- Java用NEW關鍵字來創建對象,Java提供垃圾回收的機制,它可以自動發現對象何時不再使用並繼而銷毀它。
-
異常處理
- 異常也是一種對象,它往往處於編程語言中,與程序正常執行路徑並行,在發生錯誤時執行另一條路徑。因為是完全另一條路徑執行,所以不會幹擾正常代碼的運行
- Java從一開始就內置了異常處理,它要求你必須使用它,如果沒有編寫正確的異常處理代碼,在編譯時就會報錯,這也是Java健壯性和安全性的表現
-
並發編程
- 我們想把問題分割成多個可獨立運行的任務,在程序中這些獨立運行的部分叫做線程,這就是並發
- 當多個線程訪問同一個資源的時候有可能會有問題,我們必須使某個線程鎖定某個資源,完成其任務後釋放資源,這是線程鎖也叫同步線程
-
對象存儲位置
- 寄存器:這是最快的儲存區,位於處理器內部,我們無法用程序操控它也無法感知它的存在
- 堆棧:位於RAM(隨機訪問儲存器)中,堆棧指針下移分配內存上移釋放內存,速度僅次於寄存區,Java系統必須知道所有項的生命周期以便用上下移動堆棧指針,雖然某些數據(對象引用)存儲其中,但對象本身並不在其中
- 堆:一種通用的內存池也存在RAM中,用於存放所有Java對象。不需要知道對象的生命周期,需要的時候直接NEW出一個對象堆堆自動分配空間,但當清理的時候卻要花費點時間
- 常量儲存:常量因為是不會被改變的所以通常放在程序中,也可以放在ROM(只讀存儲器)中
- 非RAM存儲:一些對象完全存活於數據之外比如:流對象和持久化對象。這種對象通常存儲在硬盤上
- 特例基本類型:創建一個並非是引用的自動變量,直接存儲在棧中,因此更加高效
- 用引用操作對象:就像遙控器操縱電視機一樣,沒有電視機遙控器還可以存在只是不能發出任何消息,所以為了安全起見創建一個引用的時候就初始化一個對象
第二節:類
-
作用域
- 作用域決定了其內部變量的可見性和生命周期,用花括號表示。但用new創建的引用對象,它可以存活於作用域之外,雖然引用對象不能用了,但是new出來的對象還一直在內存中,Java通過垃圾回收機制最終回收無用的對象,finalize方法在垃圾回收之前調用,但不推薦使用
-
類
- 用class關鍵字後面緊跟著新的類型名稱,用來抽象某一類的對象。命名方式:首字母大寫每個單詞的首字母大寫
- 依賴(uses-a)(dependence)
-
聚合(has-a)(aggregation)
-
繼承(is-a)(inheritance)
-
設計類時盡量做到高內聚低耦合
-
所有的標識符都應該以字母(A-Z或者a-z),美元符($)、或者下劃線(_)開始
- 用class關鍵字後面緊跟著新的類型名稱,用來抽象某一類的對象。命名方式:首字母大寫每個單詞的首字母大寫
-
屬性
- 屬性就是對象本身的一些描述字段,他可以是基本數據類型也可以是其他對象的引用。命名方式:首字母小寫每個單詞的首字母大寫
-
方法-參數-返回值
- 方法是對象行為的描述,可以有很多方法,利用傳遞的參數做業務處理返回想要得到的值。命名方式:首字母小寫每個單詞的首字母大寫
-
構造器:與類名相同,每個類可以有一個以上的構造器,沒有返回值,伴隨new關鍵字被調用。一個類中如果沒有構造器,系統就會默認一個無參的構造器,數值型為0,布爾型為false,對象為null
-
- 方法是對象行為的描述,可以有很多方法,利用傳遞的參數做業務處理返回想要得到的值。命名方式:首字母小寫每個單詞的首字母大寫
-
static
- static類是不被允許的,通常使用內部類實現靜態類
- static方法在類被加載後jvm就可以在運行時數據區讀取到,因此不依賴創建對象就可以直接調用類名.方法名()。可以調用其他static方法,只能調用static數據,不能用super和this調用
- static變量在jvm加載的時候只會分配一塊內存(節省內存),可以用類名.變量名來調用,private static表示私有的靜態數據。而實例變量會每new一個對象就是一塊內存
- static代碼塊通常叫做靜態代碼塊,在類加載的時候被順序執行,在構造方法之前執行
-
final
- final類不能被繼承,裏面的方法都是final的,沒有繼承所以就沒有重寫
- final方法不允許被覆蓋,為了鎖定其方法不被擴展或者為了提高效率。private方法無法繼承因此private方法默認是final的(有爭議)
- final變量一但被賦值就無法改變
- final參數可以運用但不能被改變
- final+static表示不能被改變的靜態數據或方法也叫全局常量
-
初始化數據
- 在聲明中賦值
- 在初始化塊中賦值
- 在構造方法中賦值
- 聲明>初始化塊>構造方法
- Father
-
1 package com.fengzb.java002.object; 2 3 /** 4 * @Description 測試類 5 * @Author jxb 6 * @Date 2017-06-11 23:07:24 7 */ 8 public class ObjectTest { 9 10 public static void main(String[] args) { 11 System.out.println("--jxb--ObjectTest--main:----------測試繼承----------begin"); 12 /** 13 * private 方法無法調用 14 */ 15 Person person = new Person(); 16 person.useHandEat(); 17 18 /** 19 * 向上轉型 擁有父類的可見方法,當子類重寫父類方法時,調用的是子類的方法-多態 20 */ 21 Person pMother=new Mother(); 22 pMother.useHandEat(); 23 24 /** 25 * 編譯和運行均不會報錯 26 * 向下轉型需要強制類型轉換 27 */ 28 Mother ppMother = (Mother)pMother; 29 ppMother.setName("楓"); 30 ppMother.motherDetail(); 31 32 /** 33 * 編譯不會報錯但運行會報java.lang.ClassCastException(類型轉換異常) 34 * 可以用instanceof 來判斷是否可以向下轉型 35 */ 36 Person mperson = new Person(); 37 //這裏轉換後運行會出現異常 38 //Mother mother = (Mother) mperson; 39 //mother.useHandEat(); 40 if(mperson instanceof Mother){ 41 Mother mother = (Mother) mperson; 42 mother.useHandEat(); 43 System.out.println("--jxb--ObjectTest--main:很顯然走不到這裏"); 44 } 45 System.out.println("--jxb--ObjectTest--main:----------測試繼承----------end"); 46 47 System.out.println("--jxb--ObjectTest--main:----------測試final static----------begin"); 48 49 /** 50 * address輸出的是:北京昌平,所以具體加載順序如下: 51 * 1:聲明式賦值被加載 52 * 2:靜態模塊被加載且只加載一遍(這個實際還是很有用的) 53 * 3:父類構造方法被加載 54 * 4:本身構造方法被加載 55 */ 56 Father father = new Father(); 57 Father father1 = new Father(); 58 System.out.println("--jxb--ObjectTest--main:"+Father.address); 59 /** 60 * final無法賦值 61 */ 62 //Father.TEL="18588888888"; 63 System.out.println("--jxb--ObjectTest--main:"+Father.TEL); 64 System.out.println("--jxb--ObjectTest--main:----------測試final static----------end"); 65 66 } 67 }
ObjectTest
-
包(package):將類組織起來,一般用域名的逆序作為包名。如果一個類裏面引用相同名字的外部類,可以通過inport關鍵字導入包路徑來區分
-
註釋:單行(//)以及多行註釋(/* */),註釋內容Java虛擬機會自動過濾
-
註釋文檔:JavaDoc可以生成html文檔,[email protected]:@version
Java第二章----對象和類