面向?qū)ο笏枷耄∣OP)
面向?qū)ο蟮乃季S律杠,就是當(dāng)我們遇到某個(gè)問(wèn)題域或某個(gè)程序時(shí)栈暇,首先應(yīng)該分析問(wèn)題中有哪些對(duì)象焰情,抽象出對(duì)象與對(duì)象之間的關(guān)系嗤朴。
面向?qū)ο蟪绦蛟O(shè)計(jì)具有以下特點(diǎn):
- 封裝性
- 繼承性
- 多態(tài)性
類(lèi)
類(lèi)是用于描述同一類(lèi)的對(duì)象的一個(gè)抽象的概念,類(lèi)中定義了這一類(lèi)對(duì)象所具有的靜態(tài)屬性和動(dòng)態(tài)屬性沐飘。類(lèi)可以看成一類(lèi)對(duì)象的模板游桩,對(duì)象可以看成該類(lèi)的一個(gè)具體實(shí)例牲迫。
類(lèi)是封裝對(duì)象的屬性和行為的載體,反過(guò)來(lái)說(shuō)就是具有相同屬性和行為的一類(lèi)實(shí)體稱(chēng)為類(lèi)借卧。
在Java語(yǔ)言中盹憎,類(lèi)中對(duì)象的行為是用“方法”的形式定義的,而類(lèi)包括對(duì)象的屬性和方法铐刘。
封裝
封裝是面向?qū)ο蟮暮诵乃枷肱忝俊?duì)象的屬性和行為封裝起來(lái),其載體就是類(lèi)滨达,類(lèi)通常對(duì)客戶(hù)隱藏其實(shí)現(xiàn)細(xì)節(jié)奶稠,這就是封裝思想。采用封裝思想保證了類(lèi)內(nèi)部數(shù)據(jù)結(jié)構(gòu)的完整性捡遍,應(yīng)用該類(lèi)的用戶(hù)不不能輕易地直接的操作此數(shù)據(jù)結(jié)構(gòu)锌订,只能執(zhí)行類(lèi)允許公開(kāi)的數(shù)據(jù)。
這樣就避免了外部操作對(duì)內(nèi)部數(shù)據(jù)的影響画株,提高了程序的可維護(hù)性辆飘。
繼承
類(lèi)之間的關(guān)系稱(chēng)為關(guān)聯(lián),繼承是關(guān)聯(lián)的一種谓传。在java中使用extends關(guān)鍵字來(lái)表示繼承關(guān)系蜈项。在java中,只允許單繼承续挟,也就是說(shuō) 一個(gè)類(lèi)最多只能顯示地繼承于一個(gè)父類(lèi)紧卒。但是一個(gè)類(lèi)卻可以被多個(gè)類(lèi)繼承,也就是說(shuō)一個(gè)類(lèi)可以擁有多個(gè)子類(lèi)诗祸。
子類(lèi)繼承父類(lèi)的成員變量/成員方法
當(dāng)子類(lèi)繼承了某個(gè)類(lèi)之后跑芳,便可以使用父類(lèi)中的成員變量/成員方法,但是并不是完全繼承父類(lèi)的所有成員變量/成員方法直颅。具體的原則如下:
1)能夠繼承父類(lèi)的public和protected成員變量/成員方法博个;不能夠繼承父類(lèi)的private成員變量/成員方法;
2)對(duì)于父類(lèi)的包訪問(wèn)權(quán)限成員變量/成員方法功偿,如果子類(lèi)和父類(lèi)在同一個(gè)包下盆佣,則子類(lèi)能夠繼承;否則械荷,子類(lèi)不能夠繼承共耍;
3)對(duì)于子類(lèi)可以繼承的父類(lèi)成員變量/成員方法,如果在子類(lèi)中出現(xiàn)了同名稱(chēng)的成員變量/成員方法吨瞎,則會(huì)發(fā)生隱藏現(xiàn)象征堪,即子類(lèi)的成員變量會(huì)屏蔽掉父類(lèi)的同名成員變量/成員方法。如果要在子類(lèi)中訪問(wèn)父類(lèi)中同名成員變量/成員方法关拒,需要使用super關(guān)鍵字來(lái)進(jìn)行引用。
多態(tài)
多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力。多態(tài)就是同一個(gè)接口着绊,使用不同的實(shí)例而執(zhí)行不同操作谐算。
成員變量和成員方法
在Java語(yǔ)言中對(duì)象的屬性以成員變量的形式存在,對(duì)象的方法以成員方法的形式存在归露。
根據(jù)以上代碼洲脂,Book類(lèi)中定義了一個(gè)成員變量:name
Java語(yǔ)言使用成員方法對(duì)應(yīng)于類(lèi)對(duì)象的行為就是成員方法。如以上代碼中g(shù)etName()和setName()的兩個(gè)方法剧包。
定義成員方法的語(yǔ)法格式:
權(quán)限修飾符 返回值類(lèi)型 方法名(參數(shù)類(lèi)型 參數(shù)名){
... //方法體
return 返回值恐锦;
}
成員方法可以有參數(shù),參數(shù)可以是對(duì)象疆液,也可以是基本數(shù)據(jù)類(lèi)型的變量一铅。同時(shí),成員方法也可以選擇返回值(方法中使用return關(guān)鍵字)或者不返回值(使用void關(guān)鍵字)堕油。
在成員方法中可以調(diào)用其他成員方法和類(lèi)成員變量潘飘。如上述代碼中g(shù)etName()方法調(diào)用了setName()方法。
再成員方法中可以定義一個(gè)變量掉缺,這個(gè)變量為局部變量卜录。
權(quán)限修飾符
Java中的權(quán)限修飾符包括:private、public和protected眶明。
如果一個(gè)類(lèi)的成員變量/成員方法被修飾為private艰毒,那么該成員變量/成員方法只能在本類(lèi)中被使用,在子類(lèi)和其他包的類(lèi)中是不可見(jiàn)的搜囱。
如果一個(gè)類(lèi)的成員變量/成員方法被修飾為public丑瞧,那么除了可以在本類(lèi)中使用這些數(shù)據(jù)外,還可以在子類(lèi)和其他包的類(lèi)中使用犬辰。
如果一個(gè)類(lèi)使用protected修飾符嗦篱,那么只有本包內(nèi)的該類(lèi)的子類(lèi)或其他類(lèi)可以訪問(wèn)此類(lèi)中的成員變量和成員方法。
(當(dāng)聲明類(lèi)時(shí)不適用public幌缝,protected灸促,private修飾符設(shè)置類(lèi)的權(quán)限,則這個(gè)包預(yù)設(shè)為同一個(gè)包中的類(lèi)可以調(diào)用這個(gè)類(lèi)的成員變量或成員方法涵卵。)
局部變量
在成員方法中定義的變量就是局部變量浴栽。例如:id就是getName()方法中的局部變量。形參也可以作為一個(gè)局部變量轿偎,如定義在setName(String name)方法時(shí)典鸡,String name這個(gè)形參就是一個(gè)局部變量。
局部變量是在方法被執(zhí)行時(shí)創(chuàng)建坏晦,在方法執(zhí)行結(jié)束時(shí)被銷(xiāo)毀萝玷。局部變量在使用時(shí)嫁乘,必須進(jìn)行賦值或初始化,否則會(huì)出現(xiàn)編譯錯(cuò)誤球碉。
局部變量的有效范圍
局部變量的有效范圍從該變量的聲明開(kāi)始到該變量的結(jié)束為止蜓斧。
this關(guān)鍵字
在Java語(yǔ)言中規(guī)定使用this關(guān)鍵字來(lái)代表本類(lèi)對(duì)象的引用,this關(guān)鍵字被隱式地用于引用對(duì)象的成員變量和方法睁冬。如上述代碼中挎春,this.name指的就是Book類(lèi)中的name成員變量。而this.name = name中第二個(gè)name則指的是形參name豆拨。
this除了可以跳用成員變量或成員方法之外直奋,還可以作為方法的返回值。
public Book getBook(){
return this; //返回Book類(lèi)引用
}
類(lèi)的構(gòu)造方法
在類(lèi)中除了成員方法之外施禾,海存在一種特殊類(lèi)型的方法脚线,叫做構(gòu)造方法。構(gòu)造方法是一種特殊的方法拾积,它是一個(gè)與類(lèi)同名且返回值類(lèi)型為同名類(lèi)類(lèi)型的方法殉挽。對(duì)象的創(chuàng)建就是通過(guò)構(gòu)造方法來(lái)完成,其功能主要是完成對(duì)象的初始化拓巧。當(dāng)類(lèi)實(shí)例化一個(gè)對(duì)象時(shí)會(huì)自動(dòng)調(diào)用構(gòu)造方法(構(gòu)造方法的調(diào)用是在創(chuàng)建一個(gè)對(duì)象時(shí)使用new操作進(jìn)行的)斯碌。
構(gòu)造方法分為兩種:無(wú)參構(gòu)造方法 有參構(gòu)造方法
構(gòu)造方法特點(diǎn):
- 構(gòu)造方法沒(méi)有返回值;(且不需要void關(guān)鍵字修飾
- 構(gòu)造方法的名稱(chēng)要與本類(lèi)的名稱(chēng)相同肛度。
構(gòu)造方法的定語(yǔ)語(yǔ)法格式:
public book(){
//...構(gòu)造方法體
}
1.在構(gòu)造方法中可以為成員變量賦值傻唾,這樣當(dāng)實(shí)例化一個(gè)本類(lèi)的對(duì)象時(shí),相應(yīng)的成員變量也將被初始化承耿。
2.如果類(lèi)中沒(méi)有明確定義構(gòu)造方法冠骄,編譯器會(huì)自動(dòng)創(chuàng)建一個(gè)不帶參數(shù)的默認(rèn)構(gòu)造方法。
靜態(tài)變量加袋、常量和方法
被聲明為static的變量凛辣,常量和方法被稱(chēng)為靜態(tài)成員。靜態(tài)成員屬于類(lèi)所有职烧,區(qū)別于個(gè)別對(duì)象扁誓,可以在本類(lèi)或其他類(lèi)使用類(lèi)名+“.”來(lái)調(diào)用靜態(tài)成員。
語(yǔ)法:
類(lèi)名.靜態(tài)類(lèi)成員
例:
public class StaticTest{
static double PI =3.1415; //在類(lèi)中定義一個(gè)靜態(tài)常量
static int id; //在類(lèi)中定義靜態(tài)變量
public static void method1(){
//doSomething
}
public void method2(){
System.out.println(StaticTest.PI); //調(diào)用靜態(tài)常量
System.out.println(StaticTest.id); //調(diào)用靜態(tài)變量
StaticTest.method1(); //調(diào)用靜態(tài)方法
}
}
靜態(tài)數(shù)據(jù)與靜態(tài)方法是為了提供共享數(shù)據(jù)或方法蚀之,這樣當(dāng)需要使用時(shí)蝗敢,直接使用類(lèi)名調(diào)用這些靜態(tài)成員即可。
在Java語(yǔ)言中足删,對(duì)靜態(tài)方法有兩點(diǎn)規(guī)定:
1.在靜態(tài)方法中不可以使用this關(guān)鍵字寿谴。
2.在靜態(tài)方法中不可以直接調(diào)用非靜態(tài)方法。
類(lèi)的主方法
主方法是類(lèi)的入口點(diǎn)失受,它定義了程序從何處開(kāi)始:主方法提供對(duì)程序流向的控制讶泰,Java編譯器通過(guò)主方法來(lái)執(zhí)行程序咏瑟。
主方法的語(yǔ)法如下:
public static void main(String[] args){
//方法體
}
從主方法的定義中可以看出:
1.主方法是靜態(tài)的。所以如果要直接在主方法中調(diào)用其他方法痪署,則該方法必須也是靜態(tài)的响蕴。
2.主方法沒(méi)有返回值。
3.主方法的形參為數(shù)組惠桃。其中args[0]~args[n]分別代表程序的第一個(gè)參數(shù)到第n個(gè)參數(shù),可以使用args.length獲取參數(shù)的個(gè)數(shù)辖试。
對(duì)象
對(duì)象的創(chuàng)建
Java語(yǔ)言中使用new操作符調(diào)用構(gòu)造方法創(chuàng)建對(duì)象辜王。
Test test = new Test();
Test test = new Test("a");
Test:類(lèi)名;
test:創(chuàng)建Test類(lèi)對(duì)象
new:創(chuàng)建對(duì)象操作符
"a":構(gòu)造方法的參數(shù)
test對(duì)象被創(chuàng)建出來(lái)時(shí)罐孝,就是一個(gè)對(duì)象的引用呐馆,這個(gè)引用在內(nèi)存中為對(duì)象分配了存儲(chǔ)空間。當(dāng)創(chuàng)建對(duì)象時(shí)莲兢,自動(dòng)調(diào)用構(gòu)造方法汹来,也就是說(shuō)在java語(yǔ)言中初始化與創(chuàng)建是被捆綁在一起的。
每個(gè)對(duì)象都是相互獨(dú)立的改艇,在內(nèi)存中占據(jù)獨(dú)立的內(nèi)存地址收班,并且每個(gè)對(duì)象都具有自己的生命周期,當(dāng)一個(gè)對(duì)象的生命周期結(jié)束時(shí)谒兄,對(duì)象就變成垃圾摔桦,由Java虛擬機(jī)自帶的垃圾回收機(jī)制處理,不能再被使用承疲。
訪問(wèn)對(duì)象的屬性和行為
使用new 操作符創(chuàng)建一個(gè)對(duì)象后邻耕,可以使用“對(duì)象.類(lèi)成員”來(lái)獲取對(duì)象的屬性和行為。對(duì)象的屬性和行為是通過(guò)類(lèi)成員變量和方法的形式來(lái)表示的燕鸽,所以當(dāng)對(duì)象獲取類(lèi)成員時(shí)兄世,也相應(yīng)地獲取了對(duì)象的屬性和行為。
對(duì)象的引用
語(yǔ)法:
類(lèi)名 對(duì)象引用名稱(chēng)
Book book啊研;
Book book = new Book();
Book:類(lèi)名
book:對(duì)象
new:創(chuàng)建對(duì)象操作符
注意:引用只是存放當(dāng)一個(gè)對(duì)象的內(nèi)存地址御滩,并非存放一個(gè)對(duì)象
對(duì)象的比較
在java語(yǔ)言中有兩種對(duì)象的比較方式,分別為“==”運(yùn)算符與equals()方法悲伶。實(shí)質(zhì)上這兩種方式有著本質(zhì)的區(qū)別艾恼。
“==”運(yùn)算符比較的是兩個(gè)對(duì)象引用的地址是否相同,而equals()方法用于比較兩個(gè)對(duì)象引用所指的內(nèi)容是否相等麸锉。
對(duì)象的銷(xiāo)毀
每個(gè)對(duì)象都有生命周期钠绍,當(dāng)對(duì)象的生命周期結(jié)束時(shí),分配給該對(duì)象的內(nèi)存地址將會(huì)被回收花沉。java擁有一套完整的垃圾回收機(jī)制柳爽,垃圾回收器會(huì)回收無(wú)用但占用內(nèi)存的資源媳握。
以下兩種情況的對(duì)象會(huì)被java虛擬機(jī)視為垃圾:
- 對(duì)象引用超過(guò)其作用范圍,這個(gè)對(duì)象將被視為垃圾磷脯;
- 將對(duì)象賦值為null蛾找;
雖然垃圾回收機(jī)制已經(jīng)很完善,但垃圾回收器只能回收那些由new操作符創(chuàng)建的對(duì)象赵誓,如果某些對(duì)象不是通過(guò)new操作符在內(nèi)存中獲取一塊內(nèi)存區(qū)域打毛,這種對(duì)象可能不能被垃圾回收機(jī)制所識(shí)別,所以在java中提供了一個(gè)finalize()方法俩功。這個(gè)方法時(shí)Object類(lèi)的方法幻枉,他被聲明為protected,用戶(hù)可以在自己的類(lèi)中定義這個(gè)方法诡蜓。如果定義了finalize()方法熬甫,在垃圾回收時(shí)會(huì)首先調(diào)用該方法,在下一次垃圾回收動(dòng)作發(fā)生時(shí)蔓罚,才能真正回收被對(duì)象占用的內(nèi)存椿肩。注意:有一點(diǎn)需要明確,垃圾回收或finalize()方法不保證一定會(huì)發(fā)生豺谈,如java虛擬機(jī)內(nèi)存損耗殆盡時(shí)郑象,他是不會(huì)執(zhí)行垃圾回收的。由于垃圾回收不受人為控制核无,具體執(zhí)行時(shí)間也不確定扣唱,所以finalize()方法也就無(wú)法執(zhí)行,為此团南,java提供了System.gc()方法強(qiáng)制啟動(dòng)垃圾回收器噪沙,刀子和垃圾回收器進(jìn)行清理。