一易结、面向?qū)ο笏枷?/b>
Java是面向?qū)ο蟮母呒?jí)語言,對于Java語言來說柜候,萬事萬物皆對象搞动!
它的基本思想是使用類,對象渣刷,繼承鹦肿,封裝,消息等基本概念進(jìn)行程序設(shè)計(jì)辅柴。面向?qū)ο蟪绦虻淖钚卧穷惵崂#惔砹丝陀^世界中具有某一特征的一類事物,封裝了這類事物所具有的屬性和行為碌嘀。
所以涣旨,類定義=成員變量(屬性)+方法(行為)。
面向?qū)ο蟪绦蛟O(shè)計(jì)與人類的思維習(xí)慣一致股冗,比如希望完成“兔子吃草"
這件事:
在面向過程的程序設(shè)計(jì)里开泽,一切以函數(shù)為中心,則會(huì)用如下語句來表達(dá):
吃(兔子魁瞪,草)穆律;
而在面向?qū)ο蟪绦蛟O(shè)計(jì)里,一切以對象為中心导俘,則會(huì)用如下語句來表達(dá):
兔子.吃(草)峦耘;
對比這兩條語句可以看出,面向?qū)ο笳Z句更接近自然語言語法旅薄,主謂賓一目了然辅髓。
二、類與對象的關(guān)系
類是對象的抽象少梁,對象則是類的實(shí)例洛口,一個(gè)類可以生成多個(gè)對象。對一個(gè)類定義而言凯沪,包含三種最常見的成員:構(gòu)造器第焰、成員變量和方法,而構(gòu)造器是一個(gè)類創(chuàng)建對象的根本途徑妨马,如果一個(gè)類沒有構(gòu)造器則無法創(chuàng)建實(shí)例挺举。因此杀赢,如果程序員沒有為一個(gè)類創(chuàng)建構(gòu)造器,則系統(tǒng)會(huì)為該類提供一個(gè)默認(rèn)無參的構(gòu)造器湘纵。下面定義一個(gè)簡單的Person類:
public class Person{
? ? //定義兩個(gè)成員變量:姓名和年齡
? ? public String name;
? ? public int age;
? ? //定義一個(gè)say方法
? ? public void say(String content){
? ? ? ? System.out.println(content);
? ? }
}
定義類之后就可以通過Person p = new Person()來創(chuàng)建對象了脂崔,Person對象賦給了p變量,它們在內(nèi)存中的存儲(chǔ)示意圖如下:
三梧喷、面向?qū)ο蟮娜齻€(gè)基本特征(封裝砌左,繼承和多態(tài))
1、封裝
?封裝是指將對象的實(shí)現(xiàn)細(xì)節(jié)隱藏起來铺敌,對外提供公共訪問方法汇歹,將對象的功能暴露出來。
封裝可以被認(rèn)為是一個(gè)保護(hù)屏障适刀,防止該類的代碼和數(shù)據(jù)被外部類定義的代碼隨機(jī)訪問秤朗。
適當(dāng)?shù)姆庋b可以讓程式碼更容易理解與維護(hù)煤蹭,也加強(qiáng)了程序代碼的安全性笔喉。最終目的是實(shí)現(xiàn)模塊設(shè)計(jì)的”高內(nèi)聚低耦合“。
那么硝皂,如何實(shí)現(xiàn)java的封裝呢常挚?首先來看一下java的訪問控制級(jí)別:
Java提供了4個(gè)訪問控制級(jí)別,由小到大如下圖:
從上圖可以得出稽物,實(shí)現(xiàn)一個(gè)類封裝的步驟如下:
??修改屬性的可見性(訪問級(jí)別)來限制對屬性的訪問(一般限制為private)奄毡,例如:
/**
這段代碼中,將 name 和 age 屬性設(shè)置為私有的贝或,只能本類才能訪問吼过,其他類都訪問不了,如此就對信息進(jìn)行了隱藏咪奖。
*/
public class Person {
? ? private String name;//姓名
? ? private int age;//年齡
}
? ?? 對每個(gè)值屬性提供對外的公共方法訪問盗忱,也就是創(chuàng)建一對賦值取值的方法,用于對私有屬性的訪問羊赵,例如:
public class Person{
? ? private String name;
? ? private int age;
?
? ? public int getAge(){
? ? ? return age;
? ? }
?
? ? public String getName(){
? ? ? return name;
? ? }
?
? ? public void setAge(int age){
? ? ? this.age = age;
? ? }
?
? ? public void setName(String name){
? ? ? this.name = name;
? ? }
}
采用?this?關(guān)鍵字是為了解決實(shí)例變量(private String name)和局部變量(setName(String name)中的name變量)之間發(fā)生的同名的沖突趟佃,this指當(dāng)前對象。
因此昧捷,一個(gè)類定義時(shí)闲昭,一般用private修飾成員變量,public修飾成員方法靡挥。獲取成員變量應(yīng)該用對象.get變量名()而不是對象.成員變量名序矩。
2、繼承
我們生活中有很多繼承的例子:如兔子屬于動(dòng)物的一種跋破,兔子有一般動(dòng)物的特征及行為贮泞,在java語言里可以說兔子繼承動(dòng)物楞慈,兔子是子類,動(dòng)物是父類啃擦;學(xué)生和老師都屬于人類囊蓝,有人的一般特性,所以在java語言里可以說學(xué)生和老師繼承人類令蛉。所以繼承需要符合的關(guān)系是:is-a聚霜,父類更通用,子類更具體珠叔。
?繼承是指子類可以復(fù)用父類的屬性和方法蝎宇,Java的繼承是單繼承,每個(gè)子類只有一個(gè)直接父類祷安。Java的繼承通過extends關(guān)鍵字實(shí)現(xiàn)姥芥,實(shí)現(xiàn)繼承的類稱為子類,被繼承的類稱為父類(基類或超類)汇鞭。Java繼承語法格式如下:
修飾符 class SubClass extends SuperClass{
? //類定義部分? ? ?
}
需要注意的是 Java 不支持多繼承凉唐,但支持多重繼承絮吵。
子類包含與父類同名方法的現(xiàn)象稱為方法重寫癞己,也稱為方法覆蓋。
方法的重寫要遵循“兩大兩小一大”規(guī)則譬重,“兩同”即方法名相同读整、形參列表相同簿训;“兩小”指子類方法返回值類型應(yīng)該比父類方法返回值類型要小或相等,子類方法聲明拋出的異常應(yīng)該比父類方法聲明拋出的異常類要小或相等米间;“一大”指子類方法的訪問權(quán)限應(yīng)比父類方法的訪問權(quán)限更大或相等强品。
3、多態(tài)
多態(tài)是指子類對象可以直接賦給父類變量(父類引用指向子類對象)屈糊,但運(yùn)行時(shí)依然表現(xiàn)出子類的行為特征的榛,也就是說,同一類型的對象在執(zhí)行同一個(gè)方法時(shí)另玖,可能表現(xiàn)出多種行為特征困曙。
? 多態(tài)存在的三個(gè)必要條件
繼承
重寫
父類引用指向子類對象
比如:Parent?p?=?new?Child();
當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類中是否有該方法谦去,如果沒有慷丽,則編譯錯(cuò)誤;如果有鳄哭,再去調(diào)用子類的同名方法要糊。
多態(tài)的好處:可以使程序有良好的擴(kuò)展,并可以對所有類的對象進(jìn)行通用處理妆丘。
????????在此我向大家推薦一個(gè)架構(gòu)學(xué)習(xí)交流圈:830478757 ?幫助突破瓶頸 提升思維能力
下面舉一個(gè)多態(tài)的例子:
public class Test {
? ? public static void main(String[] args) {
? ? ? show(new Cat());? // 以 Cat 對象調(diào)用 show 方法
? ? ? show(new Dog());? // 以 Dog 對象調(diào)用 show 方法
? ? ? Animal a = new Cat();? // 向上轉(zhuǎn)型?
? ? ? a.eat();? ? ? ? ? ? ? // 調(diào)用的是 Cat 的 eat
? ? ? Cat c = (Cat)a;? ? ? ? // 向下轉(zhuǎn)型?
? ? ? c.work();? ? ? ? // 調(diào)用的是 Cat 的 work
? }?
? ? public static void show(Animal a)? {
? ? ? a.eat();?
? ? ? ? // 類型判斷
? ? ? ? if (a instanceof Cat)? {? // 貓做的事情
? ? ? ? ? ? Cat c = (Cat)a;?
? ? ? ? ? ? c.work();?
? ? ? ? } else if (a instanceof Dog) { // 狗做的事情
? ? ? ? ? ? Dog c = (Dog)a;?
? ? ? ? ? ? c.work();?
? ? ? ? }?
? ? }?
}
abstract class Animal {?
? ? abstract void eat();?
}?
class Cat extends Animal {?
? ? public void eat() {?
? ? ? ? System.out.println("吃魚");?
? ? }?
? ? public void work() {?
? ? ? ? System.out.println("抓老鼠");?
? ? }?
}?
class Dog extends Animal {?
? ? public void eat() {?
? ? ? ? System.out.println("吃骨頭");?
? ? }?
? ? public void work() {?
? ? ? ? System.out.println("看家");?
? ? }?
}
執(zhí)行以上程序锄俄,輸出結(jié)果為:
吃魚
抓老鼠
吃骨頭
看家
吃魚
抓老鼠