全部章節 >>>>
本章目錄
3.1 包
生活工作中的包、文件夾
管理計算機程序和文件的目錄結構
3.1.1 自定義包
如果在程序中沒有聲明包,類將被存放在default的包中,該方式不被提倡。
語法:
package 包名
包命名規範:
包的命名規範應當體現出項目資源良好的劃分
自定義標籤類所在包命名規範:公司名稱.開發組名稱.項目名稱
例如:com.java.explorer
聲明一個包的語句必須寫在類中的第一行
3.1.2 包的導入
語法:
import 包名.類名
示例:
import java.util.*; //導入java.util包中所有的類
import java.util.ArrayList; //導入java.util包中的ArrayList類
示例:在Hero類中使用Tree類,Hero類與Tree類不在同一個包中
package com.java.oriented.dota.scene;
public class Tree {
public void clear(){
//具體業務邏輯
}
}
package com.java.oriented.dota.figure;
//由於Tree類與Hero類不在同一個包中,所以需要使用import關鍵字導入包
import com.java.oriented.dota.scene.Tree;
public class Hero {
public void eatTree(Tree tree){
//調用樹對象的clear()方法,吃掉的樹在地圖中消失
tree.clear();
}
}
3.1.3 包的訪問權限
一個包中具有缺省訪問權限的成員只能在同一個包中被引用。
如果一個包中的成員的訪問權限爲 public,那麼這些成員才能被其他包中的類所引用。
以上“成員”特指類、屬性和方法。
public成員可以被其他包中的類訪問,public類中的protected成員可以被由它派生的在其他包中的子類訪問。
package com.java.oriented.dota.scene;
public class Tree {
void clear(){ //去掉public
//具體業務邏輯
}
}
package com.java.oriented.dota.figure;
//由於Tree類與Hero類不在同一個包中,所以需要使用import關鍵字導入包
import com.java.oriented.dota.scene.Tree;
public class Hero {
public void eatTree(Tree tree){
//調用樹對象的clear()方法,吃掉的樹在地圖中消失
tree.clear();
}
}
3.1.4 實踐練習
3.2 繼承
繼承是java面向對象編程技術的一塊基石,因爲它允許創建分等級層次的類。
繼承就是子類繼承父類的特徵和行爲,使得子類對象(實例)具有父類的實例 域和方法,或子類從父類繼承方法,使得子類具有父類相同的行爲。
生活中的繼承:
3.2.1 繼承概述
- 繼承是面向對象程序設計的一個重要特徵,它是通過繼承原有類派生出子類,進而構造出更爲複雜的子類。
- 子類既有新定義的行爲特徵,又繼承了原有類的行爲特徵。
- 父類與子類存在着包含與被包含的關係,是一種is-a的關係。
- 在Java中繼承可以在現有類的基礎上進行功能的擴展,這樣能夠更加快速地開發出新類,使新類不僅可以複用當前類的特徵和行爲,而且還可以定義自己的特徵和行爲。
- 通過繼承可大幅度提高代碼的複用性,減少代碼量,便於程序的後期維護。
Java繼承語法:
[修飾符] class 子類名 extends 父類名{
//類定義部分
}
父類也稱作基類或超類
3.2.2 繼承的實現
示例:定義父類武器,以及子類聖劍和長矛
public class Weapon { //父類 武器
String name;//武器名
int attackValue;//攻擊值
//構造方法
public Weapon(String name, int attackValue) {
System.out.println("--執行武器父類Weapon的構造方法--");
this.name = name;
this.attackValue = attackValue;
}
//攻擊方法
public void attack(){
System.out.println("武器名:"+name+"\t"+"攻擊
值:"+attackValue);
}
}
public class Sword extends Weapon{ //聖劍 子類
public Sword(String name, int attackValue) {
super(name, attackValue);
}
}
public class Spear extends Weapon{ //聖劍 長矛
//構造方法
public Spear(String name,int attackValue) {
super(name, attackValue);
}
}
public class ExtendsTest { // 測試類
public static void main(String[] args){
Sword word = new Sword("聖劍",300);
word.attack();
Spear spear = new Spear("長矛",250);
spear.attack();
}
}
3.2.3 實踐練習
3.3 重載和重寫
3.3.1 重載
- 方法重載是讓類以統一的方式處理不同類型數據的一種手段。
- Java的方法重載,就是在類中可以創建多個方法,它們具有相同的名字,但具有不同的參數和不同的定義。調用方法時通過傳遞給它們的不同參數個數和參數類型來決定具體使用哪個方法。
- 方法重載也是多態的一種體現。
方法重載的規則:
方法名稱必須相同。
參數列表必須不同(個數不同、或類型不同、參數排列順序不同等)。
方法的返回類型可以相同也可以不相同。
僅僅返回類型不同不足以成爲方法重載。
注意:
參數列表不同包括:個數不同、類型不同和順序不同。
僅僅參數變量名稱不同是不可以的。
跟成員方法一樣,構造方法(構造器)也可以重載。
聲明爲final的方法不能被重載。
聲明爲static的方法不能被重載,但是能夠被再次聲明。
示例:在Book類中定義3個互爲重載的方法,它們分別計算不同情形下圖書的價格。
public class Book {
//定義3個重載方法
public float getPrice(){
return 100;
}
public float getPrice(int page){
return (float)(page*0.1);
}
public float getPrice(int page ,float discount){
return (float) (page*discount);
}
public static void main(String[] args) {
Book book=new Book();//創建Book對象
System.out.println("default圖書價格:"+book.getPrice());
System.out.println("根據頁數計算圖書價格:"+book.getPrice(268));
System.out.println("根據頁數和折扣計算圖書格:"+book.getPrice(360,0.2f));
}
}
3.3.2 重寫
在子類中可以根據需要對從父類中繼承來的方法進行重寫。
重寫的方法和被重寫的方法必須具有相同方法名稱、參數列表和返回類型。重寫方法不能使用比被重寫的方法更嚴格的訪問權限。
重寫方法不能聲明拋出比被重寫方法範圍更大的異常類型。
重寫是外殼不變,核心變。也就是說方法名不變,參數不變,具體實現可以改變。一般是在父類中聲明方法,在子類中重寫。重載是方法名不變,但參數一定要變。而且重載的方法一般都寫在一個類中。
提醒:
重寫是子類對所繼承父類相同方法的一種更改,這個更改需要遵循格式按照父類的格式。
子類重寫方法的訪問權限,拋出異常等等,都需在父類方法的控制範圍之內,但其內部的具體實現可以不同。
子類重寫方法的返回值可以爲父類中被重寫方法返回值的子類型;如果方法參數若爲子類類型,則它們是重載而不是重寫。
示例:在子類鴕鳥中重寫父類飛鳥的飛翔方法
public class Bird { // 父類 飛鳥
//Bird類的fly()方法
public void fly(){
System.out.println("我在藍天白雲間自由的飛翔...");
}
}
public class Ostrich extends Bird{// 子類 鴕鳥
public void fly(){ //重寫父類方法
System.out.println("我只能在陸地上拍拍翅膀奔跑...");
}
public void prey(){ //捕食方法
fly();
System.out.println("執行捕食方法");
}
public static void main(String[] args) {
Ostrich ostrich=new Ostrich();
ostrich.prey(); //調用ostrich對象的prey()
}
}
3.3.3 重寫覆蓋問題
子類方法的覆蓋使子類“隱藏”了父類中的方法。
如果需要訪問被子類覆蓋的方法,則可使用super關鍵字指明調用父類被覆蓋的實例方法。
示例:子類鴕鳥捕食時將使用父類飛鳥的飛翔功能。
public class Ostrich extends Bird{
public void fly(){
System.out.println("我只能在陸地上拍拍翅膀奔跑...");
}
//捕食方法
public void prey(){
//在prey()方法中使用super關鍵調用父類的fly()方法
super.fly();
System.out.println("執行捕食方法");
}
public static void main(String[] args) {
//創建Ostrich對象
Ostrich ostrich=new Ostrich();
ostrich.prey();//調用ostrich對象的fly()
}
}
3.3.4 實踐練習
3.4 多態
從一定角度來看,封裝和繼承幾乎都是爲多態而準備的。
多態是指允許不同類的對象對同一消息做出響應。即同一消息可以根據發送對象的不同而採用多種不同的行爲方式。
多態是指同一操作作用於不同的對象,可以有不同的解釋,產生不同的執行結果。
在編譯時,可以通過父類的引用指向子類對象,而在運行時,則通過父類所指向的子類對象,調用子類中重寫父類的方法。
3.4.1 多態應用
示例:指向子類的父類引用在執行重寫方法時所體現的多態性
//父類 人物
public class Figure {
protected String name;
public void attack(){
//此處不進行具體的攻擊操作,不同職業的英雄攻擊方式不同
}
public void run(){
System.out.println("在奔跑");
}
}
//子類 戰士
public class Warrior extends Figure{
//重寫父類的attack()方法
public void attack(){
System.out.println(this.name+"正在物理攻擊......");
}
}
//子類 法師
public class Master extends Figure {
//重寫父類的attack()方法
public void attack(){
System.out.println(this.name+"正在魔法攻擊......");
}
public static void main(String[] args) {
Figure master=new Master();
master.name="惡魔巫師";
Figure warrior=new Warrior();
warrior.name="撼地神牛";
master.attack();
warrior.attack();
}
}
3.4.2 引用變量的強制類型轉換
示例:調用父類引用的方法沒有在父類進行定義
//子類 法師
public class Master extends Figure {
//重寫父類的attack()方法
public void attack(){
System.out.println(this.name+"正在魔法攻擊......");
}
//子類特有的轟炸功能
public void bomb(){
System.out.println(this.name+“正在魔法轟炸......");
}
public static void main(String[] args) {
Figure figure=new Master();
figure.name="惡魔巫師";
figure.attack();
figure.bomb(); //此處編譯出錯
}
}
分析:
引用變量只能調用其編譯時類型的方法,而不能調用運行時類型的方法,即 使實際所引用的對象確實包含該方法。
如果需要讓引用變量調用運行時類型的方法,則必須將其強制類型轉換爲運 行時類型,強制類型轉換需藉助於類型轉換運算符。
3.4.3 instance of 運算符
instance of 運算符用於判斷一個實例是否爲某個類的實例
語法:
a instanceof A
判斷實例a是否爲類A的實例,如果爲真則返回true,否則返回false。
//子類 法師
public class Master extends Figure {
//重寫父類的attack()方法
public void attack(){
System.out.println(this.name+"正在魔法攻擊......");
}
//子類特有的轟炸功能
public void bomb(){
System.out.println(this.name+“正在魔法轟炸......");
}
public static void mafigurein(String[] args) {
Figure figure=new Master();
figure.name="惡魔巫師";
figure.attack();
if(figure instanceof Master )
Master master = (Master)figure; // 使用向下類型轉換
master.bomb(); //成功調用Master類的bomb
}
}
3.4.4 實踐練習
總結:
- 聲明包的語句是“package 包名”,該語句必須放在第一行,導入類的語句是 “import 包名.類名”。
- 繼承就是子類繼承父類的特徵和行爲,使得子類對象(實例)具有父類的實例 域和方法,或子類從父類繼承方法,使得子類具有父類相同的行爲。
- 子類繼承父類的語法是:“[修飾符] class 子類名 extends 父類名”。
- 重載就是在類中可以創建多個方法,它們具有相同的名字,但具有不同的參數和不同的定義。
- 重寫就是在子類方法重寫父類方法,重寫的方法和被重寫的方法必須具有相同方法名稱、參數
- 列表和返回類型。
- 多態是指同一操作作用於不同的對象,可以有不同的解釋,產生不同的執行結果。
- 在編譯時,可以通過父類的引用指向子類對象,而在運行時,則通過父類所指向的子類對象,調用子類中重寫父類的方法。