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

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

Java提供了三個訪問控制符:private、protected和public,分別代表三個訪問控制級別。
default訪問控制權限(包訪問權限)
如果類里的一個成員不使用任何訪問控制符修飾,則使用default默認訪問控制,default訪問控制的成員可以被相同包下其他類訪問。
protected訪問控制權限(子類訪問權限)
如果一個成員使用protected訪問控制符修飾,那么這個成員即可以被同一包中其他類訪問,也可以被不同包中的子類訪問。
public訪問控制權限(公共訪問權限)
如果一個成員使用public訪問控制符修飾,則可以被所有類訪問。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)
這篇文章主要介紹了SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
使用springboot單元測試對weblistener的加載測試
這篇文章主要介紹了使用springboot單元測試對weblistener的加載測試,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
Mybatisplus創(chuàng)建Spring?Boot工程打包錯誤的解決方式
最近在實戰(zhàn)springboot遇到了一些坑,記錄一下,下面這篇文章主要給大家介紹了關于Mybatisplus創(chuàng)建Spring?Boot工程打包錯誤的解決方式,文中通過圖文介紹的介紹的非常詳細,需要的朋友可以參考下2023-03-03
解決BufferedReader.readLine()遇見的坑
這篇文章主要介紹了解決BufferedReader.readLine()遇見的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12

