這一週的第一天的內容是面向對象的封裝,以及對方法的調用。實在時無法單獨拿出來單說,就結合這一節一塊兒說了。程序員
我實在是被繼承中的super用法給弄的有點暈,程序老是不能按照我想的那樣,不是說結果,而是實現過程,很明顯複雜,後來進行推敲後,原來是個人理解出了差錯。數組
先把前對象的的內容補補安全
在開始面向對象以前,咱們先來了解一下,Java的內存分配:(在以前我也說過,只是簡單的提到)jvm
Java把內存劃分爲4個部分 1. 代碼區 一、棧區 三、堆區 四、靜態區域
一、棧區(stacksegment)—由編譯器自動分配釋放,存放函數的參數值,局部變量的值等,具體方法執行結束以後,系統自動釋放JVM內存資源
二、堆區(heapsegment)—通常由程序員分配釋放,存放由new建立的對象和數組,jvm不定時查看這個對象,若是沒有引用指向這個對象就回收
三、靜態區(datasegment)—存放全局變量,靜態變量和字符串常量,不釋放
四、代碼區(codesegment)—存放程序中方法的二進制代碼,並且是多個對象共享一個代碼空間區域函數
1、面向對象的三大特性:學習
封裝、繼承、多態。測試
一、封裝this
在面向對象程式設計方法中,封裝(英語:Encapsulation)是指一種將抽象性函式接口的實現細節部份包裝、隱藏起來的方法。spa
封裝能夠被認爲是一個保護屏障,防止該類的代碼和數據被外部類定義的代碼隨機訪問。設計
要訪問該類的代碼和數據,必須經過嚴格的接口控制。
封裝最主要的功能在於咱們能修改本身的實現代碼,而不用修改那些調用咱們代碼的程序片斷。
適當的封裝可讓程式碼更容易理解與維護,也增強了程式碼的安全性。
1.1 封裝的優勢
1. 良好的封裝可以減小耦合。
2. 類內部的結構能夠自由修改。
3. 能夠對成員變量進行更精確的控制。
4. 隱藏信息,實現細節。
1.2 實現Java封裝的步驟
1. 修改屬性的可見性來限制對屬性的訪問(通常限制爲private),例如:
這段代碼中,將 name 和 age 屬性設置爲私有的,只能本類才能訪問,其餘類都訪問不了,如此就對信息進行了隱藏。
2. 對每一個值屬性提供對外的公共方法訪問,也就是建立一對賦取值方法,用於對私有屬性的訪問,例如:
1 public class Person{ 2 private String name; 3 private int age; 4 public int getAge(){ 5 return age; 6 } 7 public String getName(){ 8 return name; 9 } 10 public void setAge(int age){ 11 this.age = age; 12 } 13 public void setName(String name){ 14 this.name = name; 15 } 16 }
採用 this 關鍵字是爲了解決實例變量(private String name)和局部變量(setName(String name)中的name變量)之間發生的同名的衝突。
1.3 this
this指針:(實際上,每一個非static方法中都隱含這一個this指針指向當前正在調用該方法的對象。)
1.4 static
static(靜態的):
一、若是在一個屬性的前面加上static ,那麼這個屬性就不是某一個對象的了,而是N個對象共用的了。在靜態區存放,不釋放。
static屬性變量是屬於類自己的,沒有對象咱們仍然能夠經過類名的方式進行訪問該類內部的static屬性。(static方法也能夠)
注意:類能夠直接調用,實例化出來的對象固然也能夠進行調用。
理解:模型均可以,模型造的對象固然能夠。
二、加上static的確是屬於類自己的,可是要去訪問它必須控制符是非私有的,若是控制符是私有的,則不能直接經過類名進行訪問!!
理解:private static void a(){} private static int i;都是不能夠直接經過類名進行訪問,由於前面的控制符是private
三、非靜態的方法能夠訪問靜態成員,反之不能夠。非私有的靜態成員才能經過類名直接調用。
理解:靜態的方法和靜態的變量屬於類自己,不是靜態的方法必須經過對象進行調用,在實例化對象的同時也包含了靜態的方法,固然能夠。反之不能夠。
下面,咱們用實例來理解static的做用:
實例1:實現一個類只容許有一個對象
1 package com.wyh.Iterator; 2 3 /** 4 * @author WYH 5 * @version 2019年11月10日 上午10:18:07 6 * 該程序證實: 7 * 實現一個類只容許實例化一個對象 8 */ 9 10 class A2{ 11 public int i = 2; 12 13 private static A2 aa = new A2(); 14 15 private A2() { 16 17 } 18 19 public static A2 getA2() { 20 return aa; 21 } 22 } 23 24 public class static03 { 25 public static void main(String[] args) { 26 A2 aa1 = A2.getA2(); 27 A2 aa2 = A2.getA2(); 28 aa1.i = 90; 29 System.out.println("aa2:"+aa2.i);//說明aa1和aa2是同一個對象 30 31 if(aa1 == aa2) { 32 System.out.println("說明aa1和aa2是同一個對象"); 33 }else { 34 System.out.println("說明aa1和aa2不是同一個對象"); 35 } 36 } 37 38 }
實例2:一個類不管實例化多少對象,其中一個變量只有一個。
1 package com.wyh.Iterator; 2 3 /** 4 * @author WYH 5 * @version 2019年11月10日 上午9:32:57 6 */ 7 public class static01 { 8 private static int i; 9 10 public static01() { 11 i = i+1; 12 } 13 14 // static void add() { 15 // i = i+1; 16 // } 17 // 18 19 public static void main(String[] args) { 20 static01 s1 = new static01(); 21 // s1.add(); 22 static01 s2 = new static01(); 23 // s2.add(); 24 static01 s3 = new static01(); 25 // s3.add(); 26 static01 s4 = new static01(); 27 // s4.add(); 28 static01 s5 = new static01(); 29 // s5.add(); 30 System.out.println("總共實例化了:"+i+"個對象"); 31 } 32 33 }
二、繼承
什麼是繼承?在咱們的後面實際操做過程當中,不少時候,許多的對象擁有一些重複的操做,並且,這些對象都是同一種現實屬性的派生。例如,咱們的男人和女人都是人類,那麼人類就是男人,女人的父類,男人和女人繼承了人類這個父類,稱之爲子類。
一、繼承,咱們用extends來表示:好比剛剛說的男人繼承了人類這個類 public class woman extends human{}
二、提到了繼承父類,那繼承過來的成員變量和一些方法,咱們怎麼去使用呢?
2.1 super
終於講到使人頭疼的super了。
重寫:當子類須要父類的功能,而子類有新的內容,能夠重寫父類中的方法。在實際開發過程當中,隨着代碼量的逐漸增長,維護成了一個很大的問題,若是須要對某個方法進行修改,其自己代碼以及其子類代碼都會受到影響,而重寫則很好的解決了這個問題。方法重寫又稱爲方法覆蓋、方法複寫。
方法重寫特色
在子類和父類中,出現了方法聲明相同的狀況
子類的方法聲明要和父類相同
子類要重寫的方法,方法的權限修飾符不能比父類更低(public 、protected 、default 、private 權限依次增長)
父類私有的方法,子類不能進行方法重寫
方法重寫和方法重載的區別:
方法重寫:子類和父類中方法相同,兩個類之間的關係,函數的返回值類型、函數名、參數列表都同樣
方法重載:指在同一個類中,多個方法名相同,他們的參數列表不一樣(個數不一樣,數據類型不一樣)
重寫方法時要注意的地方:
1.方法重寫時, 方法名與形參列表必須一致。
2.方法重寫時,子類的權限修飾符必需要大於或者等於父類的權限修飾符。
3.方法重寫時,子類的返回值類型必需要小於或者 等於父類的返回值類型。
4.方法重寫時, 子類拋出的異常類型要小於或者等於父類拋出的異常類型。 Exception(最壞) RuntimeException(小壞)
先來看一個例子:
A類:(父類)
1 package day02; 2 3 /** 4 * @author WYH 5 * @version 2019年11月12日 下午2:52:37 6 */ 7 public class A { 8 9 protected String name; 10 protected String health; 11 protected String love; 12 13 14 15 public String getName() { 16 return name; 17 } 18 public String setName(String name) { 19 return this.name = name; 20 } 21 public String getHealth() { 22 return health; 23 } 24 public void setHealth(String health) { 25 this.health = health; 26 } 27 public String getLove() { 28 return love; 29 } 30 public void setLove(String love) { 31 this.love = love; 32 } 33 public A() { 34 super(); 35 // TODO Auto-generated constructor stub 36 } 37 public void eat() 38 { 39 System.out.println("吃飯!"); 40 } 41 public void work() 42 { 43 System.out.println("工做!"); 44 } 45 public void sleep() 46 { 47 System.out.println("睡覺!"); 48 } 49 50 }
B類:(子類,繼承了A父類)
1 package day02; 2 3 /** 4 * @author WYH 5 * @version 2019年11月12日 下午2:53:02 6 */ 7 public class B extends A{ 8 private int i; 9 10 11 12 public int getI() { 13 return i; 14 } 15 16 public void setI(int i) { 17 this.i = i; 18 } 19 20 public B(){ 21 super(); 22 } 23 24 public void work() 25 { 26 super.work(); //使用super關鍵字調用父類方法 27 System.out.println("學習!"); 28 System.out.println("娛樂!"); 29 30 } 31 }
D類:(子類,繼承了A父類)
1 package day02; 2 3 /** 4 * @author WYH 5 * @version 2019年11月12日 下午2:53:02 6 */ 7 public class D extends A{ 8 private int i; 9 10 11 12 public int getI() { 13 return i; 14 } 15 16 public void setI(int i) { 17 this.i = i; 18 } 19 20 public D(){ 21 super(); 22 } 23 24 public void work() 25 { 26 super.work(); //使用super關鍵字調用父類方法 27 System.out.println("學習!"); 28 System.out.println("娛樂!"); 29 30 } 31 }
C類:(測試類,主類)
1 package day02; 2 3 /** 4 * @author WYH 5 * @version 2019年11月12日 下午2:53:34 6 */ 7 public class C { 8 public static void main(String[] args) { 9 /*A aa = new A(); 10 aa.work();*/ 11 12 A bb = new B(); 13 A dd = new D(); 14 bb.name = bb.setName("456"); 15 dd.name = dd.setName("123"); 16 System.out.println(bb.name); 17 System.out.println(dd.name); 18 System.out.println(bb.getName()); 19 bb.work(); 20 } 21 22 }
解說:
咱們能夠看到,我如今父類,A類種定義了name;health;love;三個成員變量,爲了能夠實現繼承,咱們不將它定義成私有變量,同時父類裏面擁有三個方法,吃飯,睡覺,工做。
B類和D類繼承了A類,同時咱們將work方法進行了重寫,添加了本身特有的方法。
而後,咱們來看看結果:
後來,咱們發現,經過super,能夠調用父類的方法,以及能夠經過super調用父類的成員變量。這個例子很好的歸納,this指針,super的用法,重寫的用法。