Java應用程式開發學習之繼承
面對物件程式語言有三類特性,分別是封裝性、繼承性以及多型性。
本節就來簡單介紹下Java的繼承。
一、繼承的簡單介紹、特點、規則
繼承是多型的前提,如果沒有繼承,就沒有多型。
繼承主要解決的問題是:共性抽取(解決重複程式碼的問題)。
Java繼承知識點裡兩個重要的名詞:父類和子類
父類:也叫做基類、超類
子類:也叫派生類
Java繼承關係當中的特點:
1、子類可以擁有父類的內容。
2、子類還可以擁有自己專有的內容。
子類方法的返回值必須小於等於父類方法的返回值範圍。
Object類是所有類的公共最高父類(祖宗類)
java.lang.Object類是所有類的公共最高父類,java.lang.String就是Object的子類
子類方法的許可權必須[大於等於]父類方法的許可權修飾符
public > protected > (default) > private
這裡(default)不是關鍵字default,而是什麼都不寫,留空。
在Java繼承關係中,子類就是一個父類,也就是說,子類可以被當做父類看待
例如父類是員工,子類是講師,那麼講師就是一個員工,關係is->a。
二、怎麼來定義父子類之間的繼承關係
一、定義父類的格式:(就是一個普通的類定義) public class 父類名稱 { //... } 二、定義子類的格式: public class 子類名稱 extends 父類名稱 { //... }
注意:父類只能使用父類的東西,沒有任何子類的內容。
子類既可以使用父類繼承下來的東西,也可以用子類本身的東西。
1、在父子類的繼承關係中,如果成員變數重名,則建立子類物件時,訪問有兩種方式:
(1)直接通過子類物件訪問成員變數
建立的時候等號左邊是誰,就優先呼叫誰,沒有則向上找(只能由子到父這樣的順序)
(2)間接通過成員方法訪問成員變數
該方法屬於誰,就優先呼叫誰,沒有則向上找(只能由子到父這樣的順序)
2、在父子類的繼承關係中,建立子類物件,訪問成員方法的規則:
建立的物件是誰,就優先用誰,如果沒有則向上找
注意事項:
無論成員方法還是成員變數,如果沒有都是向上找父類,絕對不會向下找子類的。
三、方法重寫
概念:在繼承關係當中,方法的名稱一樣,引數列表也一樣。
方法重寫和方法過載的區別:
方法重寫是方法的名稱一樣,引數列表也一樣,也就是覆蓋、覆寫。
方法過載是方法的名稱一樣,引數列表不一樣
方法的覆蓋重寫特點:建立的是子類物件,則優先用子類方法。
@Override
可以把這個寫在方法前面,用來檢測是不是有效的覆蓋重寫,如果不是重寫,會報錯。(可選)
方法重寫的應用場景:
設計原則:
對於已經投入使用類,儘量不要進行修改
推薦一個新的類,來重複利用其中共性內容,並且新增改動新內容。例如:
定義子類的xxx方法
void xxx()
{
super.xxx(); //把父類的xxx()方法拿過來重複利用
//子類再來新增更多內容。
xx();
xxxxx();
xxxxxxx();
}
繼承關係中,父子類構造方法的訪問特點:
1.子類構造方法當中有一個預設隱藏的super呼叫,所以一定是先呼叫的父類構造方法,再呼叫子類構造方法。
2.可以通過super關鍵字來子類構造呼叫父類過載構造。
3.只有子類構造方法,才能呼叫父類構造方法
4.super的父類構造呼叫,必須是子類構造方法的第一個語句,不能一個子類構造呼叫多次super構造。
總結:
子類必須呼叫父類構造方法,不寫則贈送super();寫了則用寫了指定的super呼叫,super只能有一個,還必須是第一個。
父類的構造方法:(有參)
public xxx(int xx)
{
}
子類的構造方法:(無參)
public xxx()
{
super(10);
//..
//..
}
四、super關鍵字的用法
1、在子類的成員方法中,訪問父類的成員變數。
System.out.println(super.xx);
2、在子類的成員方法中,訪問父類的成員方法。
super.method();
3、在子類的構造方法中,訪問父類的構造方法。
public simple_member(int Money_Balance , String Name)
{
super(Money_Balance,Name);
}
五、this關鍵字的三種用法
1、在本類的成員方法中,訪問本類的成員變數。
2、在本類的成員方法中,訪問本類的另一個成員方法。
3、在本類的構造方法中,訪問本類的另一個構造方法。
在第三種用法中要注意:
this(...)呼叫也必須是構造方法的第一個語句,唯一一個
this(xxx);
super和this兩種構造呼叫,不能同時使用
六、Java繼承的特點
參考傳智Java課程學習如下:
七、抽象
如果父類當中的方法不確定如何進行{}方法體實現,那麼這就應該是一個抽象方法。
格式:
抽象方法:加上abstract關鍵字,然後去掉大括號,直接分號結束。
抽象類:抽象方法所在的類,必須是抽象類。
抽象類可以定義普通成員方法。
public abstract class xxx
{
//這是一個抽象方法,但是具體是什麼,不確定。
public abstract void xxxx();
}
如何使用抽象類和抽象方法
1.不能直接建立new抽象類物件。
2.必須用一個子類來繼承抽象父類。
3.子類必須覆蓋重寫父類當中所有的抽象方法。
覆蓋重寫(實現),去掉抽象方法的abstract關鍵字,然後補上方法大括號(實現)。
4.建立子類物件進行使用。
注意事項:
1.抽象類不能建立物件,如果建立,編譯無法通過而報錯。只能建立其非抽象子類的物件。
2.抽象類中,可以有構造方法,是供子類建立物件時,初始化父類成員使用的。
3.抽象類中,不一定包含抽象方法,但是有抽象方法的類就必須是抽象類。(應用:設計模式的介面卡模式)
4.抽象類的子類,必須重寫抽象父類中所有的抽象方法,否則,編譯無法通過而報錯,除非該子類也是抽象類。
下面來看一個Java繼承的應用,發紅包的案例:
使用者類定義:
使用者類主要定義了一些其它子類公有的資訊,達到程式碼的複用功能。
package demo;
public class User {
//使用者餘額定義
private int Money_Balance ;
//使用者名稱稱定義
private String Name ;
public User(){
}
public User(int Money_Balance , String Name)
{
this.Money_Balance = Money_Balance ;
this.Name = Name ;
}
//獲取成員名稱
public String Get_Name()
{
return this.Name ;
}
//設定餘額
public void Set_Money_Balance(int Money_Balance)
{
this.Money_Balance = Money_Balance ;
}
//獲取餘額
public int Get_Money_Balance()
{
return this.Money_Balance ;
}
//列印成員名稱和餘額
public void show()
{
System.out.println(this.Name+"有"+this.Money_Balance+"元錢");
}
}
群主類定義:
群主類主要實現的是發紅包的方法。
package demo;
import java.util.ArrayList;
public class Lord extends User{
public Lord(int Money_Balance , String Name)
{
super(Money_Balance,Name);
}
//顯示資訊
public void show()
{
super.show();
}
//發紅包的方法
public ArrayList<Integer> send(int totalMoney,int count)
{
ArrayList<Integer> list = new ArrayList<>();
int Integer_money = totalMoney / count ;
int remainder_money = totalMoney % count ;
//判斷Lord有多少錢
if(totalMoney > super.Get_Money_Balance())
{
System.out.println("餘額不足");
return list ;
}
//群主一共有多少錢,要發多少錢就從總數里扣掉這筆要發的錢
super.Set_Money_Balance(super.Get_Money_Balance()-totalMoney);
//總工要發count個紅包
for(int i = 0 ; i < count ; i++)
{
//能夠取整的
if(i < count - 1)
list.add(Integer_money);
//不能夠取整的放在最後一個紅包裡
else
list.add(Integer_money+remainder_money);
}
return list;
}
}
普通成員類定義:
普通成員主要實現收紅包的方法。
package demo;
import java.util.ArrayList;
import java.util.Random;
public class simple_member extends User{
public simple_member(int Money_Balance , String Name)
{
super(Money_Balance,Name);
}
//顯示資訊
public void show()
{
super.show();
}
//收紅包的方法
public void receive(ArrayList<Integer> list)
{
Random r = new Random();
//得到一個ArrayList的隨機索引
int rand_index = r.nextInt(list.size());
//獲取員工當前有多少錢
int member_money = super.Get_Money_Balance();
//得到移除索引所對應的數值
int delet_money = list.remove(rand_index);
//並且得到的紅包給員工本人,做加法
super.Set_Money_Balance(member_money+delet_money);
}
}
主程式編寫:
package demo;
import java.util.ArrayList;
public class Red_envelopes_main {
public static void main(String[] args) {
// TODO Auto-generated method stub
int money = 100 ;
Lord boss = new Lord(100,"老闆");
simple_member worker1 = new simple_member(0,"員工1");
simple_member worker2 = new simple_member(0,"員工2");
simple_member worker3 = new simple_member(0,"員工3");
boss.show();
worker1.show();
worker2.show();
worker3.show();
//老闆發紅包
ArrayList<Integer> list_read = boss.send(20, 3);
boss.show();
//員工收紅包
worker1.receive(list_read);
worker2.receive(list_read);
worker3.receive(list_read);
worker1.show();
worker2.show();
worker3.show();
}
}
執行結果: