一文詳解Object類和抽象類
一、抽象類是什么?
在面向?qū)ο蟮母拍钪?,所有的?duì)象都是通過(guò)類來(lái)描繪的,但是反過(guò)來(lái),并不是所有的類都是用來(lái)描繪對(duì)象的,如果一個(gè)類中沒(méi)有包含足夠的信息來(lái)描繪一個(gè)具體的對(duì)象,這樣的類就是抽象類。
由于抽象類不能實(shí)例化對(duì)象,所以抽象類必須被繼承,才能被使用。也是因?yàn)檫@個(gè)原因,通常在設(shè)計(jì)階段決定要不要設(shè)計(jì)抽象類。
父類包含了子類集合的常見(jiàn)的方法,但是由于父類本身是抽象的,所以不能使用這些方法。
二、初始抽象類
2.1 基本語(yǔ)法
在 Java 語(yǔ)言中使用 abstract class 來(lái)定義抽象類。
如下實(shí)例:
abstract class Employee { //普通的成員屬性 private String name; private String address; //構(gòu)造方法 public Employee(String name, String address) { this.name = name; this.address = address; } //普通的成員方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
注意到該 Employee 類沒(méi)有什么不同,盡管該類是抽象類,但是它仍然有 成員變量,成員方法和 構(gòu)造方法
注意:抽象類也是類,內(nèi)部可以包含普通方法和屬性,甚至構(gòu)造方法
public static void main(String[] args) { Employee employee = new Employee("zhangsan","shanxi"); }
代碼可以編譯通過(guò)嗎?
我們可以發(fā)現(xiàn)抽象類是無(wú)法實(shí)例化對(duì)象的.
2.2 繼承抽象類
1.抽象方法的權(quán)限
abstract class Shape { abstract private void func(); }
抽象類要被繼承,需要子類實(shí)現(xiàn)抽象方法,所以抽象方法的權(quán)限不能是private.
注意:抽象方法沒(méi)有加訪問(wèn)限定符時(shí),默認(rèn)是public.
abstract class Shape { abstract final void func(); }
** 抽象方法不能被final和static修飾,因?yàn)槌橄蠓椒ㄒ蛔宇愔貙?xiě)**
先寫(xiě)一個(gè)Shape抽象類:
abstract class Shape { //被abstract修飾的抽象方法,沒(méi)有方法體 abstract public void draw(); abstract void calcArea(); }
抽象類必須被繼承,并且繼承后子類要重寫(xiě)父類中的抽象方法,否則子類也是抽象類,必須要使用 abstract 修飾
class Circle extends Shape { private double r; final private static double PI = 3.14; public Circle(double r) { this.r = r; } @Override public void draw() { System.out.println("畫(huà)圓!"); } @Override void calcArea() { System.out.println("面積為: "+PI*r*r); } }
public static void main(String[] args) { Circle circle = new Circle(2); circle.draw(); circle.calcArea(); }
實(shí)現(xiàn)父類的抽象方法后,即可正常實(shí)例化
class Rect extends Shape { @Override public void draw() { } }
子類繼承抽象類時(shí),要么把抽象方法全部實(shí)現(xiàn),不然將子類繼續(xù)抽象化.
三、抽象類總結(jié)
- 1.抽象類中必須使用abstract修飾類
- 2.抽象類中可以包含普通類所能包含的成員
- 3.抽象類和普通類不一樣的是:抽象類可以包含抽象方法.
- 4.抽象方法使用abstract修飾的,這個(gè)方法沒(méi)有具體的實(shí)現(xiàn)
- 5.不能實(shí)例化抽象類
- 6.抽象類最大的意義就是被繼承
- 7.如果一個(gè)普通類繼承了一個(gè)抽象類,那么必須重寫(xiě)抽象類當(dāng)中的方法,否則寫(xiě)為抽象類
- 8.抽象方法不能是私有的,static?也就是要滿足重寫(xiě)的規(guī)則
- 9.final?不可以它和abstract是矛盾的
- 10.抽象類當(dāng)中可以有構(gòu)造方法,為了方便子類調(diào)用,來(lái)初始化類中的成員變量.
- 11.抽象類的出現(xiàn),是為了讓程序員更早的發(fā)現(xiàn)錯(cuò)誤,防止出錯(cuò),讓編譯器及時(shí)提醒我們.
四、Object類
4.1 初始Object
Java Object 類是所有類的父類,也就是說(shuō) Java 的所有類都繼承了 Object,子類可以使用 Object 的所有方法。
Object 類位于 java.lang 包中,編譯時(shí)會(huì)自動(dòng)導(dǎo)入,我們創(chuàng)建一個(gè)類時(shí),如果沒(méi)有明確繼承一個(gè)父類,那么它就會(huì)自動(dòng)繼承 Object,成為 Object 的子類。
class Person { } class Person extends Object { }
這兩種是一模一樣的.
4.2 toString
Object中的toString方法:
public static void main(String[] args) { Circle circle = new Circle(2); System.out.println(circle); }
我們要打印circle對(duì)象具體內(nèi)容的話,需要重寫(xiě)toString方法.
public String toString() { return "Circle{" + "r=" + r + '}'; }
4.3 equals
在Java中,進(jìn)行比較時(shí):
- a.如果雙等號(hào)左右兩側(cè)是基本類型變量,比較的是變量中值是否相同
- b.如果雙等號(hào)左右兩側(cè)是引用類型變量,比較的是引用變量地址是否相同
- c.如果要比較對(duì)象中內(nèi)容,必須重寫(xiě)Object中的equals方法,因?yàn)閑quals方法默認(rèn)也是按照地址比較的:
public static void main(String[] args) { Circle circle = new Circle(2); Circle circle1 = new Circle(2); int a = 1; int b = 1; System.out.println(a == b); System.out.println(circle == circle1); System.out.println(circle.equals(circle1)); }
每次new一個(gè)對(duì)象都會(huì)在堆開(kāi)辟一個(gè)新的空間.
Object定義的equals方法,在兩個(gè)對(duì)象調(diào)用時(shí)對(duì)比的是兩個(gè)對(duì)象地址是否相等,而不是具體對(duì)象中的內(nèi)容這時(shí)候我們需要重寫(xiě)equals方法.
@Override public boolean equals(Object obj) { if(obj == null) { return false; } if(this == obj) { return true; } if(!(obj instanceof Circle)) { return false; } Circle circle = (Circle)obj; return this.r == circle.r; }
比較對(duì)象中內(nèi)容是否相同的時(shí)候,一定要重寫(xiě)equals方法。
4.4 hashcode
我們可以發(fā)現(xiàn)toString方法中有使用到這個(gè)方法,我們目前只需要知道它是一個(gè)內(nèi)存地址,然后調(diào)用Integer.toHexString()方法,將這個(gè)地址以16進(jìn)制輸出。
public static void main(String[] args) { Circle circle1 = new Circle(2); Circle circle2 = new Circle(2); System.out.println(circle1.hashCode()); System.out.println(circle2.hashCode()); }
我們認(rèn)為兩個(gè)存儲(chǔ)相同值的Circle對(duì)象,在調(diào)用Object的hashcode方法時(shí),輸出的值不一樣.
//重寫(xiě)hashCode方法 @Override public int hashCode() { return Objects.hash(r); }
當(dāng)我們重寫(xiě)hashCode后,當(dāng)兩個(gè)對(duì)象存儲(chǔ)的內(nèi)容一樣時(shí),輸出的哈希值是一樣的.
結(jié)論:
- 1、hashcode方法用來(lái)確定對(duì)象在內(nèi)存中存儲(chǔ)的位置是否相同
- 2、事實(shí)上hashCode() 在散列表中才有用,在其它情況下沒(méi)用。在散列表中hashCode() 的作用是獲取對(duì)象的散列碼,進(jìn)而確定該對(duì)象在散列表中的位置。
到此這篇關(guān)于一文詳解Object類和抽象類的文章就介紹到這了,更多相關(guān)Object抽象類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于ReentrantLock的實(shí)現(xiàn)原理講解
這篇文章主要介紹了ReentrantLock的實(shí)現(xiàn)原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Mybatis動(dòng)態(tài)SQL之if、choose、where、set、trim、foreach標(biāo)記實(shí)例詳解
動(dòng)態(tài)SQL就是動(dòng)態(tài)的生成SQL。接下來(lái)通過(guò)本文給大家介紹Mybatis動(dòng)態(tài)SQL之if、choose、where、set、trim、foreach標(biāo)記實(shí)例詳解的相關(guān)知識(shí),感興趣的朋友一起看看吧2016-09-09Java實(shí)現(xiàn)的對(duì)稱加密算法AES定義與用法詳解
這篇文章主要介紹了Java實(shí)現(xiàn)的對(duì)稱加密算法AES,結(jié)合實(shí)例形式分析了對(duì)稱加密算法AES的定義、特點(diǎn)、用法及使用場(chǎng)景,需要的朋友可以參考下2018-04-04spring boot 監(jiān)聽(tīng)容器啟動(dòng)代碼實(shí)例
這篇文章主要介紹了spring boot 監(jiān)聽(tīng)容器啟動(dòng)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10手動(dòng)構(gòu)建springBoot啟動(dòng)器過(guò)程圖解
這篇文章主要介紹了手動(dòng)構(gòu)建springBoot啟動(dòng)器過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04一文詳解如何在SpringMVC的視圖中渲染模型數(shù)據(jù)
SpringMVC是一個(gè)基于Spring框架的Web框架,它提供了一種方便的方式來(lái)處理 HTTP 請(qǐng)求和響應(yīng),在SpringMVC中,視圖是用來(lái)渲染模型數(shù)據(jù)的組件,它們負(fù)責(zé)將模型數(shù)據(jù)轉(zhuǎn)換為HTML、JSON、XML等格式的響應(yīng),在本文中,我們將討論如何在SpringMVC中的視圖中渲染模型數(shù)據(jù)2023-07-07SpringBoot解決@Component無(wú)法注入其他Bean的問(wèn)題
這篇文章主要介紹了SpringBoot解決@Component無(wú)法注入其他Bean的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08使用Mybatis的PageHelper分頁(yè)工具的教程詳解
這篇文章主要介紹了使用Mybatis的PageHelper分頁(yè)工具的教程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Java使用Queryable-pageable實(shí)現(xiàn)分頁(yè)效果
這篇文章主要為大家介紹了Java如何使用Queryable-pageable從而實(shí)現(xiàn)分頁(yè)效果,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以動(dòng)手嘗試一下2022-06-06