1.多态概述
什麼是多态?
多種狀态,通一個對象在不同情況下表現出不同的狀态或行為
Java中實作多态的步驟
·要有繼承(或實作)關系
·要有方法重寫
·父類引用指向子類對象(is a 關系)
例子:
//定義父類 Animal
public classAnimal {//成員變量//姓名
privateString name;//成員方法
public voideat(){
System.out.println("正在吃東西");
}//構造方法//無參構造
publicAnimal() {
}//帶參構造
publicAnimal(String name) {this.name =name;
}//公共通路方式:getXXX() ,setXXX()
public voidsetName(String name) {this.name =name;
}publicString getName() {returnname;
}
}
//定義子類 Dog
public class Dog extendsAnimal{//需求:狗吃骨頭,是以要優化父類中的eat()方法
public voideat(){
System.out.println(this.getName()+"正在吃骨頭");
}
}
//測試類
public classTest {
public static voidmain(String[] args) {//示範多态
//多态
Animal an = newDog();
an.setName("哈士奇");
an.eat();
}
}
運作結果:
多态關系中成員方法的使用
需求:父類型變量作為參數時,可以接收任意子類對象
分析:
A:定義方法,參數類型為父類型Animal
showAnimal(Animal animal)
B:分别建立Dog類和Mouse類
C:調用showAnimal方法示範效果
//定義父類 Animal
public classAnimal {//成員變量
privateString name;//成員方法
public voideat() {
System.out.println("吃飯");
}//構造方法//無參構造
publicAnimal() {
}//帶參構造
publicAnimal(String name) {this.name =name;
}//公共通路方式:getXXX() ,setXXX()
public voidsetName(String name) {this.name =name;
}publicString getName() {returnname;
}
}
//定義子類 Dog
public class Dog extendsAnimal {//成員方法
public voideat(){
System.out.println(this.getName()+"吃骨頭");
}
}
//定義子類 Mouse
public class Mouse extendsAnimal{public voideat(){
System.out.println(this.getName()+"吃奶酪");
}
}
//測試類
public classTest {public static voidmain(String[] args) {
//用來測試Dog類和Mouse類
Dog d = newDog();
d.setName("哈士奇");
showAnimal(d);
Mouse m= newMouse();
m.setName("Jerry");
showAnimal(m);
System.out.println("==============");//多态的作用
Animal dog = newDog();
dog.setName("狗");
Animal mouse= newMouse();
mouse.setName("老鼠");
showAnimal(dog);
showAnimal(mouse);
}//傳統做法//需求:在該類中定義showAnimal方法
public static voidshowAnimal(Dog d){
d.eat();
}public static voidshowAnimal(Mouse m){
m.eat();
}//多态的做法
public static voidshowAnimal(Animal an){
an.eat();
}
}
運作結果:
多态關系中成員變量的使用
需求:子父類中定義了同名的成員變量,如何調用
分析
A:子類中定義同名屬性name并分别初始化值
String name;
B:在測試類中以多态的方式建立對象并列印name屬性值:Animal animal = new Dog();
C:在測試類中以普通方式建立對象并列印name屬性值:Dog dog = new Dog();
//定義父類 Animal
public classAnimal {
String name= "Animal";
}
//定義子類 Dog
public class Dog extendsAnimal{
String name= "Dog";
}
//測試類
public classTest {public static voidmain(String[] args) {
Animal an= newDog();
System.out.println(an.name);//Animal
Dog dog= newDog();
System.out.println(dog.name);//Dog
}
}
運作結果:
結論:
多态關系中成員變量是不能重寫
2.多态的好處和弊端
多态的好處
·可維護性:基于繼承關系,隻需要維護父類代碼,提高了代碼的複用性,大大大降低了維護程式的工作量
·可拓展性:把不同的子類對象都當做父類看待,屏蔽了不同子類對象間的差異,做出通用的代碼,以适應不同的需求
多态的弊端
不能使用子類特有成員
解決方案:
類型轉換
當需要子類特有功能時,需要進行類型轉換
向上轉型(自動型轉換)
-子類型轉換成父類型
Animal animal = new Dog();
向下轉型(強制轉換)
-父類型轉換成子類型
Dog dog =(Dog)animal;
注意事項
·隻能在繼承層次捏進行轉換(ClassCastException)
·将父類對象轉換成子類型之前,使用instanceof進行檢查
if(an.instanceof Dog){ //判斷an是否時Dog類型的對象
//是Dog類型對象
Dog dog =(Dog)animal;
}
4.抽象類的特點
抽象類的特點
1.修飾符:必須用abstract關鍵字修飾
-修飾符 abstract class 類名{}
-修飾符 abstract 傳回值類型 方法名();
2.抽象類不能被執行個體化,隻能建立子類對象
3.抽象類的子類隻有兩個選擇
-重寫父類所有抽象方法
-定義成抽象類
抽象類的成員特點
1.成員變量:
可以有普通的成員方法
也可以有成員常量(final)
2.成員方法:
可以有普通方法,也可以有抽象方法
抽象類不一定有抽象方法,有抽象方法的類一定是抽象類(或接口)
3.構造方法:
像普通類一樣有構造方法
案例:
需求:開發團隊中有程式員和經理兩種角色,他們都有姓名、工資、工号等屬性,都有工作行為,經理還要獎金屬性。請使用繼承思想設計出上述需求中的類,并分别建立對象使用
分析
A:經理和程式員都是員工,把他們的共同的屬性和行為定義子在父類Employee中,由于并不明确工作的具體内容,是以父類中工作的方法定義成抽象方法;
name ,salary, id , work()
B:定義經理類Manager,繼承Employee,屬性和行為:bonus;work();
C:定義程式員類Coder,繼承Employee,屬性和行為:work();
D:在測試類中分别建立對象并使用
//定義一個父類 抽象類 Employee
public abstract classEmployee {//成員變量//姓名
privateString name;//工号
privateString id;//工資
private doublesalary;//成員方法 抽象方法//工作
public abstract voidwork();//公共通路方式
public voidsetName(String name) {this.name =name;
}public voidsetId(String id) {this.id =id;
}public void setSalary(doublesalary) {this.salary =salary;
}publicString getName() {returnname;
}publicString getId() {returnid;
}public doublegetSalary() {returnsalary;
}//構造方法//無參構造
publicEmployee() {
}//全參構造
public Employee(String name, String id, doublesalary) {this.name =name;this.id =id;this.salary =salary;
}
}
//定義一個子類 Manager 經理類繼承父類 Employee
public class Manager extendsEmployee{//成員變量//獎金
private doublebonus;//實作抽象方法
public voidwork() {
System.out.println(this.getName()+"正在監督");
}//公共通路方式
public void setBonus(doublebonus) {this.bonus =bonus;
}public doublegetBonus() {returnbonus;
}//構造方法
publicManager() {
}public Manager(String name, String id, double salary, doublebonus) {super(name, id, salary);this.bonus =bonus;
}
}
//定義一個子類 Coder 程式員類 繼承抽象類 Employee
public class Coder extendsEmployee{//實作抽象方法
public voidwork() {
System.out.println(this.getName()+"正在寫代碼");
}//構造方法
publicCoder() {
}public Coder(String name, String id, doublesalary) {super(name, id, salary);
}
}
//測試類
public classTest {public static voidmain(String[] args) {//建立經理對象
Employee manager = newManager();
manager.setName("張三");
manager.work();//建立程式員類
Employee coder = newCoder();
coder.setName("李四");
coder.work();
}
}
運作結果:
5.final關鍵字
final的概念
最終的、最後的
final 的作用
1.修飾類:該類不能被繼承
String,System
2.修飾方法:該方法不能被重寫
不能與abstract共存
3.修飾變量:最終變量,即常量,隻能指派異常
不建議修飾引用類型資料,因為仍然可以通過引用修改對象的内部資料,意義不大
6.static關鍵字
static 的概念
靜态的
static 的作用
用于修飾類的成員:
1.成員變量:類變量
2.成員方法:類方法
調用方式:
類名.成員變量;
類名.成員方法(參數);
static 修飾成員變量
特點:被本類所有對象共享
-随意修改靜态變量的值是有風險的,為了降低風險,可以同時用final關鍵字修飾,即公有靜态常量(注意命名的變化)
static 修飾成員方法
1.靜态方法
-靜态方法中沒有對象this,是以不能通路非靜态成員
2.靜态方法的使用場景
-隻需要通路靜态成員
-不需要通路對象狀态,所需參數都由參數清單顯示提供
7.接口概述
接口的概念
接口技術用于描述具有什麼功能,但并不給出具體實作,類要遵守從接口描述的統一規則進行定義,是以,接口時對外提供的一組規則、标準
接口的定義
·定義接口使用關鍵字 interface
interface 接口名{}
·類和接口是實作關系,用implements表示
class 類名 implements 接口名
接口的特點
接口建立對象的特點:
1.接口不能執行個體化
通過多态的方式執行個體化子類對象
2.接口的子類(實作類)
可以是抽象類,也可以是普通類
如果是抽象類,不要重寫接口的方法,如果是普通類,必須重寫所有接口方法
接口繼承關系的特點:
1.接口與接口之間的關系
繼承關系,可以多繼承,格式
接口 extends 接口1,接口2,接口3.....
2.繼承和實作的差別
繼承體系的是”is a“的關系,父類中定義共性内容
實作體系的是”like a “的關系,接口中定義擴充功能
8.接口成員的特點
接口成員變量的特點
接口沒有成員變量,隻有公有的、靜态的常量
public static final 常量名 = 常量值;
接口成員方法的特點
JDK7之前,公有的、抽象方法:
public abstract 傳回值 方法名()
JDK8之後,可以有預設方法和靜态方法:
public default 傳回值類型 方法名(){}
JDK9之後,可以有私有方法:
private 傳回值類型 方法名(){}
接口構造方法的特點
接口不能夠執行個體化,也沒有需要初始化的成員
是以接口沒有構造方法