Java語言中面向?qū)ο蟮奶匦?/p>
Java自動的“無用單元收集”預(yù)防存儲漏泄和其它有關(guān)動態(tài)存儲分配和解除分配的有害錯誤。Java解釋程序也執(zhí)行許多運(yùn)行時的檢查,諸如驗(yàn)證所有數(shù)組和串訪問是否在界限之內(nèi)。下面是小編整理的關(guān)于Java語言中面向?qū)ο蟮奶匦裕M蠹艺J(rèn)真閱讀!
Java面向?qū)ο?/strong>
面向?qū)ο笫且环N程序設(shè)計(jì)方法,或者是程序設(shè)計(jì)規(guī)范,其基本思想是使用對象、類、繼承、封裝、多態(tài)等基本概念來進(jìn)行程序設(shè)計(jì)。 面向?qū)ο笫且环N符合人們思考習(xí)慣的思想,可以將復(fù)雜的事情簡單化,將程序員從執(zhí)行者轉(zhuǎn)換成了指揮者
完成需求時:
• 先要去找具有所需的功能的對象來用。
• 如果該對象不存在,那么創(chuàng)建一個具有所需功能的對象。
• 這樣簡化開發(fā)并提高代碼的復(fù)用。
面向?qū)ο蟮拈_發(fā)過程其實(shí)就是不斷的創(chuàng)建對象,使用對象,指揮對象做事情。設(shè)計(jì)的過程其實(shí)就是在管理和維護(hù)對象之間的關(guān)系。
面向?qū)ο蟮奶卣鳎?/p>
• 封裝(encapsulation)
• 繼承(inheritance)
• 多態(tài)(polymorphism)
1.封裝
概念:是指隱藏對象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅對外提供公共訪問方式。
好處:• 將變化隔離。• 便于使用。• 提高重用性。• 提高安全性。
封裝原則:
• 將不需要對外提供的內(nèi)容都隱藏起來。
• 把屬性都隱藏,提供公共方法對其訪問。
Java中可以通過對類的成員設(shè)置一定的訪問權(quán)限,實(shí)現(xiàn)類中成員的信息隱藏。
private:類中限定為private的成員,只能被這個類本身訪問。如果一個類的構(gòu)造方法聲明為private,則其它類不能生成該類的一個實(shí)例。
default:類中不加任何訪問權(quán)限限定的成員屬于缺省的(default)訪問狀態(tài),可以被這個類本身和同一個包中的類所訪問。
protected:類中限定為protected的成員,可以被這個類本身、它的子類(包括同一個包中以及不同包中的子類)和同一個包中的所有其他的類訪問。
public:類中限定為public的成員,可以被所有的類訪問。
如下面的這個student類,就是使用了封裝,將類中的屬性name 、age和score私有化,使外部不能直接訪問他們,只能通過public類型的對他們方法進(jìn)行操作。
class Student {
private String name;//聲明屬性 ,并設(shè)為私有類型,起到封裝的作用
private int age;
private int score;
public Student(String name,int age ,int score) { //構(gòu)造函數(shù),分別給name、age、score賦值
this.name= name;// :this代本類對象的引用
this.age= age;
this.score= score;
}
public String getName() { //設(shè)置getter方法,因?yàn)樽兞吭O(shè)為了私有,對象無法訪問類中的屬性,需要用getter方法獲取變量
return name;
}
public void setName(String name) { //設(shè)置setter方法,因?yàn)樽兞吭O(shè)為了私有,對象無法訪問類中的屬性,需要用setter方法給變量賦值
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScorre() {
return score;
}
public void setScorre(int score) {
this.score = score;
}
}
2.繼承
繼承是一種聯(lián)結(jié)類的層次模型,并且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類可以從現(xiàn)有的類中派生,這個過程稱為類繼承。
新類繼承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。派生類可以從它的`基類那里繼承方法和實(shí)例變量,并且類可以修改或增加新的方法使之更適合特殊的需要。
子類可以直接訪問父類中的非私有的屬性和行為。通過 extends 關(guān)鍵字讓類與類之間產(chǎn)生繼承關(guān)系。如下:class SubDemo extends Demo{}
繼承提高了代碼的復(fù)用性。
繼承的出現(xiàn)讓類與類之間產(chǎn)生了關(guān)系,提供了多態(tài)的前提
繼承的特點(diǎn):
Java只支持單繼承,不支持多繼承。
• 一個類只能有一個父類,不可以有多個父類。
• class SubDemo extends Demo{} //這是對的
• class SubDemo extends Demo1,Demo2...//這是錯的
Java支持多層繼承(繼承體系)
• class A{}
• class B extends A{}
• class C extends B{}
定義繼承需要注意:
• 不要僅為了獲取其他類中某個功能而去繼承
• 類與類之間要有所屬關(guān)系,xx1是xx2的一種。
如:
class Ren { //父類
int age=20;
String name="wk";
Super.sho
public void show() {
System.out.println("姓名:"+name+" 年齡:"+age);
}
}
class Sudents extends Ren {//子類Sudents繼承了父類Ren
int score=90;//增加了新的屬性
int age= super.age+1;//使用super標(biāo)記父類中的元素,修改了Ren中age的值
public void show() {//重寫了父類中的方法( 覆蓋時,子類方法權(quán)限一定要大于等于父類方法權(quán)限,靜態(tài)只能覆蓋靜態(tài)。)
System.out.println("姓名:"+name+" 年齡:"+age+" 分?jǐn)?shù):"+ score);// Sudents繼承了Ren,所以Ren中的屬性name和age在Sudents可以直接使用
}
}
public class Preson {
public static void main(String[] args) {
Ren ren = new Ren();//聲明一個Ren對象
Sudents sudents = new Sudents();//聲明一個Sudents對象
ren.show();
sudents.show();
}
}
程序運(yùn)行結(jié)果是:
super和this的用法相同:this代表本類應(yīng)用 ;super代表父類引用 。當(dāng)子父類出現(xiàn)同名成員時,可以用super進(jìn)行區(qū)分 ,子類要調(diào)用父類構(gòu)造函數(shù)時,可以使用super語句。
在子類覆蓋方法中,繼續(xù)使用被覆蓋的方法可以通過super.函數(shù)名獲取。
注意:
1. 子類中所有的構(gòu)造函數(shù)默認(rèn)都會訪問父類中空參數(shù)的構(gòu)造函數(shù),因?yàn)槊恳粋構(gòu)造函數(shù)的第一行都有一條默認(rèn)的語句 super();子類會具備父類中的數(shù)據(jù),所以要先明確父類是如何對這些數(shù)據(jù)初始化的。當(dāng)父類中沒有空參數(shù)的構(gòu)造函數(shù)時,子類的構(gòu)造函數(shù) 必須通過this或者super語句指定要訪問的構(gòu)造函數(shù)。
2. 覆蓋時,子類方法權(quán)限一定要大于等于父類方法權(quán)限
靜態(tài)只能覆蓋靜態(tài)。
父類中的私有方法不可以被覆蓋。
3.被final修飾的類是一個最終類,不可以被繼承。
被final修飾的方法是一個最終方法,不可以被覆蓋。
被final修飾的變量是一個常量,只能賦值一次
內(nèi)部類只能訪問被final修飾的局部變量。
4. 繼承與重載:一是子類與父類的關(guān)系,二是重載方法的調(diào)用問題。
3.多態(tài)
方法的重寫、重載與動態(tài)連接構(gòu)成多態(tài)性。Java只允許單繼承,這樣做雖然保證了繼承關(guān)系的簡單明了,但是功能上有很大的限制,所以,Java引入了多態(tài)性的概念。此外,抽象類和接口也是解決單繼承規(guī)定限制的重要手段。同時,多態(tài)也是面向?qū)ο缶幊痰木杷凇?/p>
多態(tài)性:發(fā)送消息給某個對象,讓該對象自行決定響應(yīng)何種行為。
通過將子類對象引用賦值給超類對象引用變量來實(shí)現(xiàn)動態(tài)方法調(diào)用。
java 的這種機(jī)制遵循一個原則:當(dāng)超類對象引用變量引用子類對象時,被引用對象的類型而不是引用變量的類型決定了調(diào)用誰的成員方法,但是這個被調(diào)用的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。
1. 如果a是類A的一個引用,那么,a可以指向類A的一個實(shí)例,或者說指向類A的一個子類。
2. 如果a是接口A的一個引用,那么,a必須指向?qū)崿F(xiàn)了接口A的一個類的實(shí)例。
要理解多態(tài)性,首先要知道什么是“向上轉(zhuǎn)型”。
子類Cat繼承了Animal類,那么后者就是前者是父類。
Cat c = new Cat();//實(shí)例化一個Cat的對象,
Animal a = new Cat();//定義了一個Animal類型的引用,指向新建的Cat類型的對象
由于Cat是繼承自它的父類Animal,所以Animal類型的引用是可以指向Cat類型的對象的。那么這樣做的什么意義是:因?yàn)樽宇愂菍Ω割惖囊粋改進(jìn)和擴(kuò)充,所以一般子類在功能上較父類更強(qiáng)大,屬性較父類更獨(dú)特,
定義一個父類類型的引用指向一個子類的對象既可以使用子類強(qiáng)大的功能,又可以抽取父類的共性。
所以,父類類型的引用可以調(diào)用父類中定義的所有屬性和方法,但是對于子類中定義而父類中沒有的方法,它是無可奈何的;
同時,父類中的一個方法只有在在父類中定義而在子類中沒有重寫的情況下,才可以被父類類型的引用調(diào)用;
對于父類中定義的方法,如果子類中重寫了該方法,那么父類類型的引用將會調(diào)用子類中的這個方法,這就是動態(tài)連接。
如這段程序:
class Father{
public void func1(){
func2();
}
public void func2(){//這是父類中的func2()方法,因?yàn)橄旅娴淖宇愔兄貙懥嗽摲椒?/p>
//所以在父類類型的引用中調(diào)用時,這個方法將不再有效
//取而代之的是將調(diào)用子類中重寫的func2()方法
System.out.println("AAA");
}
}
class Child extends Father{
//func1(int i)是對func1()方法的一個重載
//由于在父類中沒有定義這個方法,所以它不能被父類類型的引用調(diào)用
//所以在下面的main方法中child.func1(68)是不對的
public void func1(int i){
System.out.println("BBB");
}
//func2()重寫了父類Father中的func2()方法
//如果父類類型的引用中調(diào)用了func2()方法,那么必然是子類中重寫的這個方法
public void func2(){
System.out.println("CCC");
}
}
public class PolymorphismTest {
public static void main(String[] args) {
Father child = new Child();
child.func1();//打印結(jié)果將會是什么?
}
}
這是個很典型的多態(tài)的例子。子類Child繼承了父類Father,并重載了父類的func1()方法,重寫了父類的func2()方法。重載后的func1(int i)和func1()不再是同一個方法,由于父類中沒有func1(int i),那么,父類類型的引用child就不能調(diào)用func1(int i)方法。而子類重寫了func2()方法,那么父類類型的引用child在調(diào)用該方法時將會調(diào)用子類中重寫的func2()。
所以程序運(yùn)行結(jié)果應(yīng)該是“CCC”。
實(shí)現(xiàn)多態(tài),有二種方式,覆蓋(override),重載(overload)。
覆蓋,是指子類重新定義父類的虛函數(shù)的做法。它是覆蓋了一個方法并且對其重寫,以求達(dá)到不同的作用。在覆蓋要注意以下的幾點(diǎn):
1、覆蓋的方法的標(biāo)志必須要和被覆蓋的方法的標(biāo)志完全匹配,才能達(dá)到覆蓋的效果;
2、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;
3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;
4、被覆蓋的方法不能為private,否則在其子類中只是新定義了一個方法,并沒有對其進(jìn)行覆蓋。
重載,是指允許存在多個同名函數(shù),而這些函數(shù)的參數(shù)表不同(或許參數(shù)個數(shù)不同,或許參數(shù)類型不同,或許兩者都不同)。它是指我們可以定義一些名稱相同的方法,通過定義不同的輸入?yún)?shù)來區(qū)分這些方法,然后再調(diào)用時,在使用重載要注意以下的幾點(diǎn):
1、在使用重載時只能通過不同的參數(shù)樣式。例如,不同的參數(shù)類型,不同的參數(shù)個數(shù),不同的參數(shù)順序(當(dāng)然,同一方法內(nèi)的幾個參數(shù)類型必須不一樣,例如可以是fun(int,float),但是不能為fun(int,int));
2、不能通過訪問權(quán)限、返回類型、拋出的異常進(jìn)行重載;
3、方法的異常類型和數(shù)目不會對重載造成影響;
4、對于繼承來說,如果某一方法在父類中是訪問權(quán)限是priavte,那么就不能在子類對其進(jìn)行重載,如果定義的話,也只是定義了一個新方法,而不會達(dá)到重載的效果。
多態(tài)也有弊端:當(dāng)父類引用指向子類對象時,雖然提高了擴(kuò)展性,但是只能訪問父類中具備的方法,不可以訪問子類中特有的方法。(前期不能使用后期產(chǎn)生的功能,即訪問的局限性)
【Java語言中面向?qū)ο蟮奶匦浴肯嚓P(guān)文章:
Java面向?qū)ο笤O(shè)計(jì)的經(jīng)驗(yàn)原則10-12
java面向?qū)ο缶幊填}庫及答案11-14
2017年Java面向?qū)ο竺嬖囶}05-19
java程序10個面向?qū)ο笤O(shè)計(jì)原則05-25