- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- Java當中的類(lèi)和對象以及代碼塊是怎樣的
這篇文章將為大家詳細講解有關(guān)Java當中的類(lèi)和對象以及代碼塊是怎樣的,文章內容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
java 是一門(mén)面向對象的語(yǔ)言,所謂面向對象有別于面向過(guò)程,面向對象是只需對象之間的交互即可完成任務(wù),但是面向過(guò)程的話(huà),需要我們將每一個(gè)步驟都詳細地做出來(lái)。比如,以洗衣服為例,如果是面向過(guò)程來(lái)襲衣服,那么我們首先需要衣服,然后放入盆中,之后加水,放洗衣粉,最后搓揉。但是如果面向對象的話(huà),第一步只需要找對象,找出衣服,洗衣粉,洗衣機,水這些對象,然后全部放到洗衣機里面就行了。這就是對象之間的交互。
java 當中的類(lèi)是對象的綜合,大打個(gè)比方,對象是房子,那么類(lèi)就是設計圖紙,每一個(gè)對象都是類(lèi)具體的個(gè)體。
總之,通過(guò)上面的分析,我們不難得出這樣的結論:類(lèi)似對象的統稱(chēng),對象就是這個(gè)類(lèi)的具體化實(shí)例,一個(gè)類(lèi)可以產(chǎn)生無(wú)數個(gè)對象。那么但我在寫(xiě)代碼的是就要進(jìn)行類(lèi)的實(shí)例化,即從類(lèi)(也就是模板)中抽出一個(gè)具體的對象(相當于實(shí)物)。
基本語(yǔ)法:
//創(chuàng )建類(lèi) class <class_name> { field;//屬性 method;//成員方法 } //實(shí)例化一個(gè)對象 <class_name> <對象名> = new <class_name>();
class 為定義類(lèi)的關(guān)鍵字,ClassName 為類(lèi)的名字,{}中為類(lèi)的主體。(注意:java的類(lèi)的命名是使用大駝峰,此處附上 java 組成部分的命名規則)
在類(lèi)中 但是在成員方法外面 的元素可以稱(chēng)其為:字段 / 屬性 / 成員變量(三種皆可)。
類(lèi)中的函數稱(chēng)為:成員方法。
類(lèi)的實(shí)例化方法:
class Person { public int age; //字段 public String name; public String sex; public void eat() { //方法 system.out.println("吃飯"); } public void sleep() { system.out.println("睡覺(jué)"); } }
class Person { //創(chuàng )建一個(gè)類(lèi) public String name; //成員變量 public int age; public void eat() { int a = 0;//局部變量 System.out.println("吃飯"); } } class Test { //創(chuàng )建一個(gè)類(lèi) public static void main(String[] args) {//主函數 Person person = new person(); //實(shí)例化出來(lái)一個(gè)具體對象 System.out.println(person.name);//打印出來(lái) System.out.println(person.age); person.eat(); } } //執行結果 null 0
注意事項:
如上圖的第 13 行和第 14 行代碼,使用點(diǎn)號可以訪(fǎng)問(wèn)實(shí)例化對象里面的字段
如果成員變量沒(méi)有賦初始值
那么引用類(lèi)型默認是 NULL,基本類(lèi)型默認是0
如果是boolean類(lèi)型的,默認是false
如果是char 類(lèi)型的,默認是 “\u0000”(其實(shí)就是空)
訪(fǎng)問(wèn)既包含了讀也包含了寫(xiě),讀,即可以用點(diǎn)號找到成員變量 ,寫(xiě),即可以給他賦值(本人認為這是一句廢話(huà),但是教科書(shū)看到了就bb一句)
此外,如果將引用設為null 那么后面再用點(diǎn)號來(lái)引用的話(huà)就會(huì )發(fā)生空指針異常,代碼就會(huì )報錯。(如下圖所示)
第 11 行實(shí)例化時(shí)person 是一個(gè)引用變量,此時(shí)會(huì )在計算機的??臻g里面開(kāi)辟一塊空間用于存放 person,在堆上開(kāi)辟一塊空間用于存放對象,person 引用的就是 ??臻g上面的對象。
同樣地,第五行中的 a 因為它處在函數之中所以說(shuō)它是一個(gè)局部變量,所以它是被存到了??臻g當中的。
java 中的方法說(shuō)白了就是函數,本質(zhì)上就是 對象做出的一種行為
class Person { public int age = 18; public String name = "張三"; public void show() { System.out.println("我叫 + name,今年 + age + 歲"); } } class test { public static void main(String[] args) { Person person = new Person(); person.show(); } }
如上,就是說(shuō)張三這個(gè)對象他有一個(gè)要執行的動(dòng)作叫做 show
但是若想要想創(chuàng )建一個(gè)其他對象,再用show打印的話(huà),需要 person 用點(diǎn)號來(lái)引用類(lèi)里面的相關(guān)屬性
Person person2 = new Person(); person2.name = "李四"; person2.age = 20; person2.show();
但是要注意的是,此處的代碼最上面 那個(gè)Person 類(lèi)在示例化的時(shí)候就已經(jīng)給成員變量賦初值了,這其實(shí)是不對的,因為上面已經(jīng)說(shuō)過(guò)了,類(lèi)其實(shí)是一切對象的總和,他是不可以這樣被具體化的(簡(jiǎn)單來(lái)講其實(shí)就是不可能所有人都叫張三)。
注意事項:在真正開(kāi)發(fā)的時(shí)候我們總不可能每當要打印的時(shí)候都去寫(xiě)show 函數的,所以是有快捷方法的,那就是 toString 方法,鼠標右鍵點(diǎn)擊一下找到generate 點(diǎn)擊之后然后就會(huì )跳轉,之后就可以找到了。
其實(shí)原理就是 println 的打印酒氣本源其實(shí)是調用了一個(gè)叫做 object 的類(lèi) 里面的 toString 方法,這里我們的操作就是重寫(xiě)該方法,這樣改完之后下面的代碼再用 println 打印的時(shí)候就可以直接打出我們想要的效果了。
如上圖兩處紅色的方框便是我們更改的,那么之后每次打印代碼輸出我們想要的效果。如下圖,上面一行是 show()函數輸出的結果,而下面一行是 重寫(xiě) toString 輸出的效果
(static 可以修飾的有:字段、方法、代碼塊、類(lèi))
被 static 修飾的東西不需要實(shí)例化對象,用對象去點(diǎn)xx 來(lái)訪(fǎng)問(wèn),他是可以直接用類(lèi)名點(diǎn)xx 來(lái)訪(fǎng)問(wèn)。
靜態(tài)的成員變量(或稱(chēng):類(lèi)變量)是獨立放在方法區的,只有一份,以下面的例題為例
class TestDemo{ public int a; public static int count; } public class Main{ public static void main(String[] args) { TestDemo t1 = new TestDemo(); t1.a++; TestDemo.count++; System.out.println(t1.a); System.out.println(TestDemo.count); System.out.println("============"); t2 = new TestDemo(); t2.a++; TestDemo.count++; System.out.println(t2.a); System.out.println(TestDemo.count); } }
所以由a 和count 的存儲方式就可以很容易得出答案,每當我們新實(shí)例化一個(gè)對象,a 就會(huì )隨之重創(chuàng ),所以a 是會(huì )變的,但是 count只有一份,只存于方法區,所以 當重新 new 一個(gè)對象的時(shí)候,count 會(huì )繼承上一次的值。
靜態(tài)方法還是開(kāi)辟棧幀的
靜態(tài)方法是可以直接被調用的,不需要像普通方法那樣想實(shí)例化對象再用對象來(lái)引用。也因此主函數的前面是要加 static的 ,因為static 是可以讓主函數直接通過(guò)jvm 來(lái)調用的,如果不用這種方式的話(huà)那么將必須在主函數里面 new 一個(gè)對象,讓對象來(lái)調用主函數,但是主函數目前的問(wèn)題是,new 對象必須在主函數里面,但問(wèn)題是我現在主函數進(jìn)都進(jìn)不來(lái),要想進(jìn)來(lái)就必須調用主函數,要調用就必須在主函數里面 new 對象,很明顯,這是一個(gè)自相矛盾的事情,要想解決這個(gè)矛盾就必須給主函數加上 static。
非靜態(tài)方法可以直接調用靜態(tài)方法和非靜態(tài)方法(就是直接在其內部寫(xiě)上函數名加括號就代表調用),但是靜態(tài)方法不可直接調用非靜態(tài)方法,能直接調用的只有靜態(tài)方法,也就是說(shuō)主函數要想直接調用其他方法,那就必須要讓其他函數加上 static ,不然的話(huà)還要再創(chuàng )建對象,就很麻煩。
本質(zhì)上是使用private 和 public 和這兩個(gè)關(guān)鍵字來(lái)實(shí)現函數的封裝。因為我們之前寫(xiě)的代碼都是就直接用 public 來(lái)修飾的,這樣的,我們就必須要特地去了解類(lèi)里面的情況,這會(huì )讓代碼寫(xiě)起來(lái)非常麻煩,并且如果類(lèi)的創(chuàng )建者篡改了原來(lái)類(lèi)里面成員變量的名字,那么后面的代碼也要跟著(zhù)改,安全系數很低。所以只要我們用 private 來(lái)封裝成員變量,讓使用者不能直接和成員變量產(chǎn)生聯(lián)系,而是和類(lèi)里面的函數產(chǎn)生聯(lián)系。如果成員變量產(chǎn)生變更,類(lèi)的調用者不需要做出任何修改。
總而言之,當被 private 修飾之后它的權限就被降低了,只能在當前類(lèi)里面使用。被 private 修飾的只能用類(lèi)名來(lái)引用。
getter 和 setter
但是當我們修改自己的封裝的字段的時(shí)候,不可能每次都把 getName()和setName ()寫(xiě)出來(lái),所以就可以直接使用快捷的方式,鼠標右擊 選中g(shù)enerate 再選中 自己要操作的項即可。(以下為示例),還有 this 表示當前所在對象的引用。
構造方法特點(diǎn):沒(méi)有返回值,方法的名字和類(lèi)名是相同的。
//以下為一個(gè)無(wú)參數的構造方法示例 public Person() { }
構造方法的作用是用來(lái)初始化對象的,即在對象還未創(chuàng )建的時(shí)候為對象的成員變量賦初值,因為對象的創(chuàng )建是要分兩步走的,先為對象分配內存,再為對象分配合適的構造方法,也就是說(shuō)當我們想要在構造方法當中提前給對象賦值的時(shí)候是可以用 this的,而且由于 this 本質(zhì)上是在對象創(chuàng )建后 jvm 給該對象分配的相應的指針,但是也正是也因為this 可以在構造函數之中使用(此時(shí)的對象還沒(méi)有完全創(chuàng )建好)這就可以說(shuō)明 this 其實(shí)是對象的引用,并非對象本身。
在我們實(shí)例化對象的時(shí)候,編譯器會(huì )默認攜帶一個(gè)無(wú)參數構造方法,但是如果同一個(gè)類(lèi)里面已經(jīng)有了其他構造方法,那么就不會(huì )自動(dòng)攜帶這種方法。以下三段代碼皆為構造方法,并且他們的關(guān)系是重載。
this. 成員變量
this. 成員方法
this ( ) 用 this 來(lái)調用構造函數,構造函數里面有幾個(gè)參數 this 的括號里面就有幾個(gè)參數(注意,this 調用構造方法必須放在第一行)
另外,之所以說(shuō) this 是一個(gè)引用對象而不是對象是因為,對象的產(chǎn)生要分兩步走,第一步是為對象分配內存,第二步是調用合適的構造方法,這兩步完成了之后才能說(shuō)我們的對象被創(chuàng )建了,但是,如果說(shuō)我們的 this 在一個(gè)構造方法之中創(chuàng )建的,就可以很明顯看出 this 不是對象而是引用對象,因為此時(shí)的 this 還在構造函數的代碼中,也就是說(shuō) this 使用時(shí)構造函數對象還沒(méi)有被創(chuàng )建出來(lái),所以說(shuō)這個(gè)時(shí)候的 this 僅僅只是對象的引用。
大多數時(shí)候類(lèi)里面使用 this 的時(shí)候,對象還沒(méi)有被創(chuàng )建出來(lái),這里的 this 就是當前類(lèi)的對象的引用。
此外,靜態(tài)方法當中不能出現 this (靜態(tài)只能靠類(lèi)名來(lái)引用)。
引用是否只能存在于棧上?
答:不一定,因為當你在類(lèi)里面創(chuàng )建一個(gè)成員變量是數組的時(shí)候,在你的對象實(shí)例化之后,數組的那個(gè)引用變量就會(huì )被放到對象上面,但是數組的引用變量本質(zhì)上還是引用它會(huì )指向自己數組里面的元素的。
class Person { private String name; private int age; private int[] elem = new int[10]; }//以下為原理圖
引用可以指向引用嗎?
答:不可以,引用只能指向對象。
Person person = new person(); person1 = new person(); person1 = new person(); person1 = new person(); person1 = new person();
從上面這串代碼可以明顯看出,person1 這個(gè)引用指向的對象一再被賦予新的對象,但是盡管如此這并不意味著(zhù) person1 就同時(shí)指向了多個(gè)對象,最終有效的對象只有第五行,也就是說(shuō),person1 指向了第五行的那個(gè)對象,其他的都沒(méi)用了。
一個(gè)引用被賦值null 代表它不指向任何對象
person = null;//示例
代碼塊分為
本地代碼塊(定義在方法里面的)//非重點(diǎn)
實(shí)例代碼塊(構造代碼塊)
{ this.age = 19; }//用于初始化成員變量
靜態(tài)代碼塊
static { }//用于提請準備數據
同步代碼塊(暫不講)
在程序執行的時(shí)候,執行順序為:靜態(tài)代碼塊先執行(即便放在最后面也是如此),之后實(shí)例代碼塊再執行,最后執行構造方法。還有,就是在一個(gè)類(lèi)之中,靜態(tài)的代碼只執行一次。
并且當一段代碼之中只有相同類(lèi)型的,就會(huì )安從上往下的順序執行。例如,如果一個(gè)類(lèi)之中既有靜態(tài)的字段,又有靜態(tài)代碼塊,那么誰(shuí)在前面,誰(shuí)先執行。
(構造代碼塊)
{ this.age = 19; }//用于初始化成員變量
靜態(tài)代碼塊
static { }//用于提前準備數據
同步代碼塊(暫不講)
在程序執行的時(shí)候,執行順序為:靜態(tài)代碼塊先執行(即便放在最后面也是如此),之后實(shí)例代碼塊再執行,最后執行構造方法。還有,就是在一個(gè)類(lèi)之中,靜態(tài)的代碼只執行一次。
并且當一段代碼之中只有相同類(lèi)型的,就會(huì )安從上往下的順序執行。例如,如果一個(gè)類(lèi)之中既有靜態(tài)的字段,又有靜態(tài)代碼塊,那么誰(shuí)在前面,誰(shuí)先執行。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站