JAVA中方法的聲明及使用方式(繼承、多態(tài)、封裝)
一、寫在前面
今天就來(lái)總結(jié)一下JAVA中方法的聲明及使用,即繼承、多態(tài)、封裝。
其實(shí)關(guān)于三大特性對(duì)于學(xué)習(xí)JAVA的同學(xué)來(lái)說(shuō)都是基本的了,畢竟只要接觸Java這些都是先要認(rèn)識(shí)的,接下來(lái)就系統(tǒng)總結(jié)一下。
二、繼承
先來(lái)說(shuō)說(shuō)繼承,所謂繼承本質(zhì)就是實(shí)現(xiàn)代碼的復(fù)用,防止重復(fù)的代碼多次書寫,當(dāng)一個(gè)類繼承一個(gè)類的時(shí)候,該類中就會(huì)擁有另外一個(gè)類中的所有代碼

2.1 繼承的注意事項(xiàng)
只支持單繼承,即一個(gè)子類只允許有一個(gè)父類,但是可以實(shí)現(xiàn)多級(jí)繼承,及子類擁有唯一的父類,而父類還可以再繼承。
子類可以擁有父類的屬性和方法。
子類可以擁有自己的屬性和方法。
子類可以重寫覆蓋父類的方法。
2.2 繼承的特點(diǎn)
- 提高代碼復(fù)用性。
- 父類的屬性方法可以用于子類。
- 可以輕松的定義子類。
- 使設(shè)計(jì)應(yīng)用程序變得簡(jiǎn)單。
2.3 繼承的使用
1,在父子類關(guān)系繼承中,如果成員變量重名,則創(chuàng)建子類對(duì)象時(shí),訪問(wèn)有兩種方式。
a:直接通過(guò)子類對(duì)象訪問(wèn)成員變量
List item
等號(hào)左邊是誰(shuí),就優(yōu)先使用誰(shuí),如果沒(méi)有就向上找。
b:間接通過(guò)成員方法訪問(wèn)成員變量
該方法屬于誰(shuí),誰(shuí)就優(yōu)先使用,如果沒(méi)有就向上找。
public class FU {
int numFU = 10;
int num = 100;
public void method(){
System.out.println("父類成員變量:"+numFU);
}
public void methodFU(){
System.out.println("父類成員方法!");
}
}
public class Zi extends FU{
int numZi = 20;
int num = 200;
public void method(){
System.out.println("子類成員變量:"+numFU);
}
public void methodZi(){
System.out.println("子類方法!");
}
}
public class ExtendDemo {
public static void main(String[] args) {
FU fu = new FU();
// 父類的實(shí)體對(duì)象只能調(diào)用父類的成員變量
System.out.println("父類:" + fu.numFU); // 結(jié)果:10
Zi zi = new Zi();
System.out.println("調(diào)用父類:" + zi.numFU); // 結(jié)果:10
System.out.println("子類:" + zi.numZi); // 結(jié)果:20
/** 輸出結(jié)果為200,證明在重名情況下,如果子類中存在則優(yōu)先使用,
* 如果不存在則去父類查找,但如果父類也沒(méi)有那么編譯期就會(huì)報(bào)錯(cuò)。
*/
System.out.println(zi.num); // 結(jié)果:200
/**
* 通過(guò)成員方法調(diào)用成員變量
*/
zi.method(); // 結(jié)果:10
}
}
2,同理:
? 成員方法也是一樣的,創(chuàng)建的對(duì)象是誰(shuí),就優(yōu)先使用誰(shuí),如果沒(méi)有則直接向上找。
? 注意事項(xiàng):
? 無(wú)論是成員變量還是成員方法,如果沒(méi)有都是向上父類中查找,絕對(duì)不會(huì)向下查找子類的。
3,在繼承關(guān)系中,關(guān)于成員變量的使用:
- 局部成員變量:直接使用
- 本類成員變量:this.成員變量
- 父類成員變量:super.父類成員變量
int numZi = 10;
public void method() {
int numMethod = 20;
System.out.println(numMethod); // 訪問(wèn)局部變量
System.out.println(this.numZi); // 訪問(wèn)本類成員變量
2.4 重寫和重載
2.4.1 重寫(override)
重寫是子類對(duì)父類的允許訪問(wèn)的方法的實(shí)現(xiàn)過(guò)程進(jìn)行重新編寫, 返回值和形參都不能改變。
即外殼不變,核心重寫!
class Animal{
public void move(){
System.out.println("動(dòng)物行走!");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal 對(duì)象
Animal b = new Dog(); // Dog 對(duì)象
a.move();// 執(zhí)行 Animal 類的方法
b.move();//執(zhí)行 Dog 類的方法
}
}
重寫的規(guī)則:
1,參數(shù)列表必須與被重寫方法相同。
2,訪問(wèn)權(quán)限不能比父類中被重寫的方法的訪問(wèn)權(quán)限更低(public>protected>(default)>private)。
3,父類成員的方法只能被它的子類重寫。
4,被final修飾的方法不能被重寫。
5,構(gòu)造方法不能
2.4.2 重載(overload)
重載是在一個(gè)類里面,方法名字相同,而參數(shù)不同。返回類型可以相同也可以不同。每個(gè)重載的方法(或者構(gòu)造函數(shù))都必須有一個(gè)獨(dú)一無(wú)二的參數(shù)類型列表。
? 最常用的地方就是構(gòu)造器的重載。
public class Overloading {
public int test(){
System.out.println("test1");
return 1;
}
public void test(int a){
System.out.println("test2");
}
//以下兩個(gè)參數(shù)類型順序不同
public String test(int a,String s){
System.out.println("test3");
return "returntest3";
}
public String test(String s,int a){
System.out.println("test4");
return "returntest4";
}
public static void main(String[] args){
Overloading o = new Overloading();
System.out.println(o.test());
o.test(1);
System.out.println(o.test(1,"test3"));
System.out.println(o.test("test4",1));
}
}
重載規(guī)則:
1,被重載的方法必須改變參數(shù)列表(參數(shù)個(gè)數(shù)或者類型不一樣)。
2,被重載的方法可以改變返回類型。
3,被重載的方法可以改變?cè)L問(wèn)修飾符。
2.4.3 this,super關(guān)鍵字
super()關(guān)鍵字的用法:
- 子類的成員方法中,訪問(wèn)父類的成員變量。
- 子類的成員方法中,訪問(wèn)父類的成員方法。
- 子類的構(gòu)造方法中,訪問(wèn)父類的構(gòu)造方法。
this關(guān)鍵字用法:
- 本類成員方法中,訪問(wèn)本類的成員變量。
- 本類成員方法中,訪問(wèn)本類的另一個(gè)成員方法。
- 本類的構(gòu)造方法中,訪問(wèn)本類的另一個(gè)構(gòu)造方法。
? 注意:
this關(guān)鍵字同super一樣,必須在構(gòu)造方法的第一個(gè)語(yǔ)句,且是唯一的。
this與super不能同時(shí)存在。
2.4.4 補(bǔ)充概念
隱藏
父類和子類擁有相同名字的屬性或者方法( 方法隱藏只有一種形式,就是父類和子類存在相同的靜態(tài)方法)時(shí),父類的同名的屬性或者方法形式上不見(jiàn)了,實(shí)際是還是存在的。
隱藏是對(duì)于靜態(tài)方法和成員變量(靜態(tài)變量和實(shí)例變量)而言的
public class Animal {
String name;
int age;
int legs;
public void eat(){
System.out.println("動(dòng)物要吃飯");
};
//類方法,靜態(tài)方法
//通過(guò)類就可以直接調(diào)用
public static void run(){
System.out.println("動(dòng)物在奔跑");
}
}
public class Cat extends Animal {
//重寫父類方法
public void eat() {
System.out.println("小貓吃魚");
}
//隱藏父類的run方法
public static void run(){
System.out.println("小貓?jiān)诒寂?);
}
}
對(duì)象轉(zhuǎn)型
引用類型和對(duì)象類型不一致的情況下的轉(zhuǎn)換問(wèn)題
子類轉(zhuǎn)父類(向上轉(zhuǎn)型)
Animal a = new Animal(); Cat c = new Cat(); a = c;
一個(gè)很簡(jiǎn)單的判別辦法,把右邊的當(dāng)做左邊來(lái)用,看說(shuō)得通不。右邊c引用所指向的對(duì)象的類型是 貓
左邊a引用的類型是 普通動(dòng)物,把貓 當(dāng)做 普通動(dòng)物,說(shuō)不說(shuō)得通? 說(shuō)得通,就可以轉(zhuǎn)
父類轉(zhuǎn)子類(向下轉(zhuǎn)型)
父類轉(zhuǎn)子類,有的時(shí)候行,有的時(shí)候不行,所以必須進(jìn)行強(qiáng)制轉(zhuǎn)換。強(qiáng)制轉(zhuǎn)換的意思就是 轉(zhuǎn)換有風(fēng)險(xiǎn),風(fēng)險(xiǎn)自擔(dān)。
可以的情況
Animal a = new Animal(); Cat c = new Cat(); a = c; c = (Cat) a; 不可以的情況 Animal a = new Animal(); Cat c = new Cat(); Dog d = new Dog(); a = d; c = (Cat) a; 沒(méi)有繼承關(guān)系的兩個(gè)類,互相轉(zhuǎn)換
沒(méi)有繼承關(guān)系的兩個(gè)類,互相轉(zhuǎn)換,一定會(huì)失敗。
雖然Cat和Dog都繼承了Animal,但是彼此沒(méi)有互相繼承關(guān)系
- 實(shí)現(xiàn)類轉(zhuǎn)換成接口(向上轉(zhuǎn)型)
- 接口轉(zhuǎn)換成實(shí)現(xiàn)類(向下轉(zhuǎn)型)
構(gòu)造器
子類是不繼承父類的構(gòu)造器(構(gòu)造方法或者構(gòu)造函數(shù))的,它只是調(diào)用(隱式或顯式)。
如果父類的構(gòu)造器帶有參數(shù),則必須在子類的構(gòu)造器中顯式地通過(guò) super 關(guān)鍵字調(diào)用父類的構(gòu)造器并配以適當(dāng)?shù)膮?shù)列表。
如果父類構(gòu)造器沒(méi)有參數(shù),則在子類的構(gòu)造器中不需要使用 super 關(guān)鍵字調(diào)用父類構(gòu)造器,系統(tǒng)會(huì)自動(dòng)調(diào)用父類的無(wú)參構(gòu)造器。
三、多態(tài)
3.1 定義和優(yōu)點(diǎn)
定義:
- 多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力。
- 多態(tài)就是同一個(gè)接口,使用不同的實(shí)例而執(zhí)行不同操作。
優(yōu)點(diǎn):
- 1. 消除類型之間的耦合關(guān)系;
- 2. 可替換性;
- 3. 可擴(kuò)充性;
- 4. 接口性;
- 5. 靈活性;
- 6. 簡(jiǎn)化性;
3.2 多態(tài)的體現(xiàn)形式
繼承父類引用指向子類重寫
注意:在多態(tài)中,編譯看左邊,運(yùn)行看右邊
public class MultiDemo {
public static void main(String[] args) {
// 多態(tài)的引用,就是向上轉(zhuǎn)型
Animals dog = new Dog();
dog.eat();
Animals cat = new Cat();
cat.eat();
// 如果要調(diào)用父類中沒(méi)有的方法,則要向下轉(zhuǎn)型
Dog dogDown = (Dog)dog;
dogDown.watchDoor();
}
}
class Animals {
public void eat(){
System.out.println("動(dòng)物吃飯!");
}
}
class Dog extends Animals{
public void eat(){
System.out.println("狗在吃骨頭!");
}
public void watchDoor(){
System.out.println("狗看門!");
}
}
class Cat extends Animals{
public void eat(){
System.out.println("貓?jiān)诔贼~!");
}
}
例如:
在設(shè)計(jì)房子時(shí),大門的設(shè)計(jì)應(yīng)該開進(jìn)不同型號(hào)車輛,如打開一扇門,可以開進(jìn)摩托車;打開兩扇門,可以開進(jìn)小汽車;如果需要,打開三扇門,允許開進(jìn)貨車等。
同樣是門,由于不同參數(shù),可以完成不同的功能,這個(gè)門具有多態(tài)性。
3.3 向上轉(zhuǎn)型
- 格式:父類名稱 對(duì)象名 = new 子類名稱();
- 含義:右側(cè)創(chuàng)建一個(gè)子類對(duì)象,把它當(dāng)作父類來(lái)使用。
- 注意:向上轉(zhuǎn)型一定是安全的。
- 缺點(diǎn):一旦向上轉(zhuǎn)型,子類中原本特有的方法就不能再被調(diào)用了。
四、封裝
4.1 封裝的特性
在面向?qū)ο蟪淌皆O(shè)計(jì)方法中,封裝(Encapsulation)是指一種將抽象性函式接口的實(shí)現(xiàn)細(xì)節(jié)部分包裝、隱藏起來(lái)的方法。
封裝可以被認(rèn)為是一個(gè)保護(hù)屏障,防止該類的代碼和數(shù)據(jù)被外部類定義的代碼隨機(jī)訪問(wèn);要訪問(wèn)該類的代碼和數(shù)據(jù),必須通過(guò)嚴(yán)格的接口控制;封裝最主要的功能在于我們能修改自己的實(shí)現(xiàn)代碼,而不用修改那些調(diào)用我們代碼的程序片段;適當(dāng)?shù)姆庋b可以讓程式碼更容易理解與維護(hù),也加強(qiáng)了程式碼的安全性。
封裝的特點(diǎn)
- 對(duì)成員變量實(shí)行更準(zhǔn)確的控制。
- 封裝可以隱藏內(nèi)部程序?qū)崿F(xiàn)的細(xì)節(jié)。
- 良好的封裝能夠減少代碼之間的耦合度。
- 外部成員無(wú)法修改已封裝好的程序代碼。方便數(shù)據(jù)檢查,有利于保護(hù)對(duì)象信息的完整性,同時(shí)也提高程序的安全性。便于修改,體高代碼的可維護(hù)性。
4.2 封裝的實(shí)現(xiàn)
使用private修飾符,表示最小的訪問(wèn)權(quán)限。
對(duì)成員變量的訪問(wèn),統(tǒng)一提供setXXX,getXXX方法。
下面請(qǐng)看一個(gè)Student實(shí)體對(duì)象類:
public class Student implements Serializable {
private Long id;
private String name;
private Integer sex;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
}
分析:對(duì)于上面的一個(gè)實(shí)體對(duì)象,我想大家都已經(jīng)很熟悉了。將對(duì)象中的成員變量進(jìn)行私有化,外部程序是無(wú)法訪問(wèn)的。但是我們對(duì)外提供了訪問(wèn)的方式,就是set和get方法。
? 而對(duì)于這樣一個(gè)實(shí)體對(duì)象,外部程序只有賦值和獲取值的權(quán)限,是無(wú)法對(duì)內(nèi)部進(jìn)行修改,因此我們還可以在內(nèi)部進(jìn)行一些邏輯上的判斷等,來(lái)完成我們業(yè)務(wù)上的需要。
? 到這里應(yīng)該就明白封裝對(duì)于我們的程序是多么重要。下面再來(lái)說(shuō)說(shuō)繼承的那點(diǎn)事。
修改屬性的可見(jiàn)性來(lái)限制對(duì)屬性的訪問(wèn)(一般限制為private),例如
```java
public class People {
//將 name 和 age 屬性設(shè)置為私有的,只能本類才能訪問(wèn),其他類都訪問(wèn)不了,如此就對(duì)信息進(jìn)行了隱藏。
private String name;
private int age;
}
對(duì)每個(gè)值屬性提供對(duì)外的公共方法訪問(wèn),也就是創(chuàng)建一對(duì)賦取值方法,用于對(duì)私有屬性的訪問(wèn),例如:
public class People{
//采用 this 關(guān)鍵字是為了解決實(shí)例變量(private String name)和局部變量(setName(String name)中的name變量)之間發(fā)生的同名的沖突。
private String name;
private int age;
?
public String getName(){
return name;
}
?
public void setName(String name){
this.name = name;
}
}
4.3 成員的訪問(wèn)權(quán)限

Java提供了三個(gè)訪問(wèn)控制符:private、protected和public,分別代表三個(gè)訪問(wèn)控制級(jí)別。
default訪問(wèn)控制權(quán)限(包訪問(wèn)權(quán)限)
如果類里的一個(gè)成員不使用任何訪問(wèn)控制符修飾,則使用default默認(rèn)訪問(wèn)控制,default訪問(wèn)控制的成員可以被相同包下其他類訪問(wèn)。
protected訪問(wèn)控制權(quán)限(子類訪問(wèn)權(quán)限)
如果一個(gè)成員使用protected訪問(wèn)控制符修飾,那么這個(gè)成員即可以被同一包中其他類訪問(wèn),也可以被不同包中的子類訪問(wèn)。
public訪問(wèn)控制權(quán)限(公共訪問(wèn)權(quán)限)
如果一個(gè)成員使用public訪問(wèn)控制符修飾,則可以被所有類訪問(wèn)。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring項(xiàng)目中使用Junit單元測(cè)試并配置數(shù)據(jù)源的操作
這篇文章主要介紹了Spring項(xiàng)目中使用Junit單元測(cè)試并配置數(shù)據(jù)源的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)
這篇文章主要介紹了SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
springboot整合quartz實(shí)現(xiàn)定時(shí)任務(wù)示例
spring支持多種定時(shí)任務(wù)的實(shí)現(xiàn)。我們來(lái)介紹下使用spring的定時(shí)器和使用quartz定時(shí)器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
使用springboot單元測(cè)試對(duì)weblistener的加載測(cè)試
這篇文章主要介紹了使用springboot單元測(cè)試對(duì)weblistener的加載測(cè)試,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
Mybatisplus創(chuàng)建Spring?Boot工程打包錯(cuò)誤的解決方式
最近在實(shí)戰(zhàn)springboot遇到了一些坑,記錄一下,下面這篇文章主要給大家介紹了關(guān)于Mybatisplus創(chuàng)建Spring?Boot工程打包錯(cuò)誤的解決方式,文中通過(guò)圖文介紹的介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03
解決BufferedReader.readLine()遇見(jiàn)的坑
這篇文章主要介紹了解決BufferedReader.readLine()遇見(jiàn)的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Java策略模式實(shí)現(xiàn)簡(jiǎn)單購(gòu)物車功能
這篇文章主要介紹了Java策略模式實(shí)現(xiàn)簡(jiǎn)單地購(gòu)物車,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
java多線程關(guān)鍵字final和static詳解
這篇文章主要介紹了java多線程關(guān)鍵字final和static詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01

