實際的開發中,引用類型的使用非常重要,也是非常普遍的。我們可以在理解基本類型的使用方式基礎上,進一步去掌握引用類型的使用方式。基本類型可以作爲成員變量、作爲方法的參數、作爲方法的返回值,那麼當然引用類型也是可以的。
類作爲成員變量
在定義一個類Role(遊戲角色)時,代碼如下:
class Role {
int id; // 角色id
int blood; // 生命值
String name; // 角色名稱
}
使用 int
類型表示 角色id和生命值,使用 String
類型表示姓名。此時, String
本身就是引用類型,由於使用的方式類似常量,所以往往忽略了它是引用類型的存在。如果我們繼續豐富這個類的定義,給 Role
增加武器,穿戴裝備等屬性,我們將如何編寫呢?
定義武器類,將增加攻擊能力:
lass Weapon {
String name; // 武器名稱
int hurt; // 傷害值
}
定義穿戴盔甲類,將增加防禦能力,也就是提升生命值:
class Armour {
String name;// 裝備名稱
int protect;// 防禦值
}
修改角色類:
class Role {
int id;
int blood;
String name;
// 添加武器屬性
Weapon wp;
// 添加盔甲屬性
Armour ar;
// 提供get/set方法
public Weapon getWp() {
return wp;
}
public void setWeapon(Weapon wp) {
this.wp = wp;
}
public Armour getArmour() {
return ar;
}
public void setArmour(Armour ar) {
this.ar = ar;
}
// 攻擊方法
public void attack(){
System.out.println("使用"+ wp.getName() +", 造成"+wp.getHurt()+"點傷害");
}
// 穿戴盔甲
public void wear(){
// 增加防禦,就是增加blood值
this.blood += ar.getProtect();
System.out.println("穿上"+ar.getName()+", 生命值增加"+ar.getProtect());
}
}
測試類:
public class Test {
public static void main(String[] args) {
// 創建Weapon 對象
Weapon wp = new Weapon("屠龍刀" , 999999);
// 創建Armour 對象
Armour ar = new Armour("麒麟甲",10000);
// 創建Role 對象
Role r = new Role();
// 設置武器屬性
r.setWeapon(wp);
// 設置盔甲屬性
r.setArmour(ar);
// 攻擊
r.attack();//使用屠龍刀,造成999999點傷害
// 穿戴盔甲
r.wear();//穿上麒麟甲 ,生命值增加10000
}
}
類作爲成員變量時,對它進行賦值的操作,實際上,是賦給它該類的一個對象。
接口作爲成員變量
接口是對方法的封裝,對應遊戲當中,可以看作是擴展遊戲角色的技能。所以,如果想擴展更強大技能,我們在Role
中,可以增加接口作爲成員變量,來設置不同的技能。
定義接口:
// 法術攻擊
public interface FaShuSkill {
public abstract void faShuAttack();
}
定義角色類:
public class Role {
FaShuSkill fs;
public void setFaShuSkill(FaShuSkill fs) {
this.fs = fs;
}
// 法術攻擊
public void faShuSkillAttack(){
System.out.print("發動法術攻擊:");
fs.faShuAttack();
System.out.println("攻擊完畢");
}
}
定義測試類:
public class Test {
public static void main(String[] args) {
// 創建遊戲角色
Role role = new Role();
// 設置角色法術技能
role.setFaShuSkill(new FaShuSkill() {
@Override
public void faShuAttack() {
System.out.println("縱橫天下");
}
});
// 發動法術攻擊
role.faShuSkillAttack();
//發動法術攻擊:縱橫天下
//攻擊完畢
// 更換技能
role.setFaShuSkill(new FaShuSkill() {
@Override
public void faShuAttack() {
System.out.println("逆轉乾坤");
}
});
// 發動法術攻擊
role.faShuSkillAttack();
//發動法術攻擊:逆轉乾坤
//攻擊完畢
}
}
我們使用一個接口,作爲成員變量,以便隨時更換技能,這樣的設計更爲靈活,增強了程序的擴展性。
接口作爲成員變量時,對它進行賦值的操作,實際上,是賦給它該接口的一個子類對象(實現類對象)。
接口作爲方法參數和返回值類型
當接口作爲方法的參數時,需要傳遞什麼呢?當接口作爲方法的返回值類型時,需要返回什麼呢?對,其實都是它的子類對象。 ArrayList
類我們並不陌生,查看API我們發現,實際上,它是 java.util.List
接口的實現類。所以,當我們看見 List
接口作爲參數或者返回值類型時,當然可以將 ArrayList 的對象進行傳遞或返回。
請觀察如下方法:獲取某集合中所有的偶數。
定義方法:
public static List<Integer> getEvenNum(List<Integer> list) {
// 創建保存偶數的集合
ArrayList<Integer> evenList = new ArrayList<>();
// 遍歷集合list,判斷元素爲偶數,就添加到evenList中
for (int i = 0; i < list.size(); i++) {
Integer integer = list.get(i);
if (integer % 2 == 0) {
evenList.add(integer);
}
}
/*
返回偶數集合
因爲getEvenNum方法的返回值類型是List,而ArrayList是List的子類,
所以evenList可以返回
*/
return evenList;
}
調用方法:
public class Test {
public static void main(String[] args) {
// 創建ArrayList集合,並添加數字
ArrayList<Integer> srcList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
srcList.add(i);
}
/*
獲取偶數集合
因爲getEvenNum方法的參數是List,而ArrayList是List的子類,
所以srcList可以傳遞
*/
List list = getEvenNum(srcList);
System.out.println(list);
}
}
接口作爲參數時,傳遞它的子類對象。
接口作爲返回值類型時,返回它的子類對象。
我是知識的搬運工,該篇文章內容藉助於高端IT教育品牌——黑馬程序員。