學習Java語言程序設計也有一段時間了。現在我想對封裝、繼承和多態,在Java中面向對象的三大特徵,總結一下我的理解,不妥當的地方望大家包涵。
封裝。給我的感覺封裝就是一個包裝,一個代碼是否健壯,與用不用封裝有很大的關係,封裝就像是包裹一個禮物,不僅讓禮物看起來更加精美,而且還完善了內容。請看代碼:
class Person { private String name; private int age; public void say() { System.out.println("我是"+this.getName()+" 年齡"+this.getAge()); } public String getName() { return name; } public void setName(String n) { name = n; } public int getAge() { return age; } public void setAge(int a) { if(a>=0&&a<=200) { ge = a; } } } public class PersonTest { public static void main(String[] args) { Person p = new Person(); p.setName("張三"); p.setAge(-30); p.say(); } }
定義一個Person類,它擁有兩個屬性name和age,把兩個屬性封裝。人都會說話,再定義一個say()的方法,say()方法是打印得到參數姓名和年齡。分別使用getter方法,讓對象可以獲得屬性,分別使用setter方法,讓對象可以修改屬性,其中在setAge()方法中加入if判斷條件,如果接收到的年齡參數在0~200之間,才把年齡a賦給age,否則不執行。在PersonTest的測試類中,創造一個Person類型的對象p,對象p產生了,我們用setter方法給對象p起名“張三”,新出生的一個人,我們疏忽了,年齡給了負數,“-30”歲,然後用對象p調用say()方法,讓p說話,打印結果是“我是張三 年齡0”,非常符合實際不是嗎?剛剛出生的張三,年齡當然是從無到有,實現這個功能主要是因爲對age屬性進行了封裝,把屬性保護起來,即使我們給錯了信息,依然能夠正確的表達,在修改年齡信息的時候setter方法中的判斷起到了決定性的作用,讓年齡屬性不能隨意修改,老師給我們的建議也都是屬性儘量去封裝,現在理解的還是抽象,雖然我沒有實踐的經驗,可是我不難想象,如果在工作中把我們需要的屬性封裝,保護起來,那麼就能減少一些麻煩。
繼承。繼承給我的概念就像是數學當中全集和子集的關係似的。全集範圍更大,子集屬於全集。子類繼承父類,那就是兒子可以把老子的東西直接拿過來用,因爲他“繼承”了你的衣鉢,而且一個兒子只能有一個親生父親,這就是單繼承。當然如果父親有一些隱藏的東西(就是我們之前講到的封裝過的屬性),那時不能直接拿來的,得換一種渠道,那就是後話了。代碼如下:
class Person { String name; int age; } class Student extends Person{ String number; } public class ExtendsTest { public static void main(String[] args) { Student s= new Student(); System.out.println(s.name); System.out.println(s.age); System.out.println(s.number); } }
定義一個繼承測試,一個Person類,代表人,一個Student類,代表學生這個羣體,人有名字、年齡,學生有他獨有的學號,衆所周知,人這個概念範圍更廣,學生是一種人,所以Student類就繼承Person類,當我們創造一個學生對象s,他可以有屬性名字和年齡,這不是他自己類中的屬性,這是他繼承下來Person類的屬性,不難想象,學生是一種人,當然也擁有姓名和年齡了,繼承的子類功能更加豐富,不僅有父類的全部,還有自己獨特的東西,這就是繼承的魅力,子類擴展了父類。
多態。我想這是在繼承上的更進一步。多態,就是多種形態,每個兒子都學會了父親的唯一的一個絕活,然後每個兒子根據自己的個性演繹出了屬於自己的絕活。
public class ZooTest { public static void main(String[] args) { Animal[] animals = { new Cat(), new Monkey(), new Cat(), new Mule(), new Dog(), new Monkey() }; for(Animal a:animals){ a.eat(); } } } class Animal { void eat() { System.out.println("動物吃東西"); } } class Cat extends Animal { void eat() { System.out.println("貓吃魚"); } } class Dog extends Animal { void eat() { System.out.println("狗啃骨頭"); } } class Monkey extends Animal { void eat() { System.out.println("猴吃香蕉"); } } class Mule extends Animal { void eat() { System.out.println("騾子吃飼料"); } }
定義一個Animal類,貓、狗、猴和騾子都是動物,所以Cat類、Dog類、Monkey類和Mule類繼承Animal類,Animal類有一個eat()方法,就是“動物吃東西”,然後每個動物都有自己各自的食物,子類覆寫父類的eat方法,覆蓋成自己類需要的方法,定義一個Animal容器,讓裏面裝Animal,創造對象分別是兩隻貓、一隻狗、兩隻猴和一隻騾子。用增強型for循環讓動物們進食,遍歷每個對象,調用eat()方法,結果是:
貓吃魚
猴吃香蕉
貓吃魚
騾子吃飼料
狗啃骨頭
猴吃香蕉
每個動物去吃自己的食物,結果很明顯,對吧?
這就是我目前理解的封裝、繼承和多態,希望我以後會有更深層次的理解。