1. 多態(tài)的概述
1.1 Java種實現(xiàn)多態(tài)的步驟
- 要有繼承(或?qū)崿F(xiàn))關(guān)系
- 要有方法重寫
- 父類引用指向子類對象
多態(tài)中調(diào)用成員方法是編譯看左(左邊的類型有沒有這個成員)
運行看右(運行時具體用的是右邊類中的成員)
1.2 多態(tài)的使用場景
父類型可以作為形參的數(shù)據(jù)類型锰什,這樣可以接收其任意的子類對象
1.3 多態(tài)中調(diào)用成員變量
多態(tài)中調(diào)用成員變量没咙,遵循編譯看左,運行也看左
所以下圖返回結(jié)果分別是Animal和Dog
1.4 多態(tài)的好處和弊端
多態(tài)的好處:可維護性克懊、可擴展性
多態(tài)的弊端:父類引用不能使用子類的特有成員
解決多態(tài)弊端的方法:通過類型轉(zhuǎn)換實現(xiàn)
注意:只能在繼承層次內(nèi)轉(zhuǎn)換旅挤,否則會報ClassCaseException異常
將父類對象轉(zhuǎn)換成子類前儒搭,使用instanceof進行檢查
2. 抽象類
抽象類中的成員比普通類多一種:抽象方法魂仍,其他和普通類一樣
抽象類的子類如果是普通類赊舶,必須重寫所有的抽象方法;如果是抽象類,則不用重寫抽象方法
在開發(fā)中描姚,子類一般有兩個構(gòu)造方法
子類的空參構(gòu)造訪問父類的空參構(gòu)造
子類的全參構(gòu)造訪問父類的全參構(gòu)造
package cn.case1;
public abstract class Employee {
// 定義成員變量
private String name;
private double salary;
private int id;
public Employee() {
}
public Employee(String name, double salary, int id) {
this.name = name;
this.salary = salary;
this.id = id;
}
// 定義成員方法
public abstract void work();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
// 子類Employee
package cn.case1;
public class Manager extends Employee{
private double bouns;
public Manager() {
super(); // 可以不寫
}
public Manager(String name, double salary, int id, double bouns) {
super(name, salary, id);
this.bouns = bouns;
}
@Override
public void work() {
System.out.println("Manager is working");
}
public double getBouns() {
return bouns;
}
public void setBouns(double bouns) {
this.bouns = bouns;
}
}
// 子類Coder
package cn.case1;
public class Coder extends Employee{
@Override
public void work() {
System.out.println("coder is working");
}
public Coder() {
super(); // 可以不寫
}
public Coder(String name, double salary, int id) {
super(name, salary, id);
}
}
// 測試類
package cn.case1;
public class Test {
public static void main(String[] args) {
Employee em = new Coder();
em.work();
Employee em2 = new Manager();
em.work();
// ===============================
Coder co = new Coder("xiaoli:", 12000, 1001);
System.out.println("Name:" + co.getName());
System.out.println("Salary:" + co.getSalary());
System.out.println("Id:" + co.getId());
System.out.println("=============================");
Manager ma = new Manager("xiaowang", 15000, 1000, 3000);
System.out.println("Name:" + ma.getName());
System.out.println("Salary:" + ma.getSalary());
System.out.println("Id:" + ma.getId());
System.out.println("Bonus:" + ma.getBouns());
}
}
3. final關(guān)鍵字
final的作用:用于修飾類、方法和變量
final修飾的類:不能被繼承怯邪,但是可以繼承其他的類
final修飾的方法:不能被重寫
final修飾的變量:是一個常量绊寻,值只能設(shè)置一次
4. static關(guān)鍵字
4.1 修飾成員變量
static修飾的成員變量被本類所有對象共享
public final static String DEPARTMENT_NAME = "開發(fā)部";
4.2 修飾成員方法
靜態(tài)方法:靜態(tài)方法中沒有對象this,所以不能訪問非靜態(tài)成員
靜態(tài)方法的使用場景:
如果某方法只訪問靜態(tài)成員,并且不需要通過對象名的形式調(diào)用榛斯,就可以考慮將其定義為靜態(tài)方法
5. 接口
5.1 接口的概念
package cn.case2;
public interface Smoking {
public abstract void smoke();
}
// 定義接口的實現(xiàn)類
package cn.case2;
public class Teacher implements Smoking{
@Override
public void smoke() {
System.out.println("吸煙有害健康");
}
}
// 測試類
package cn.case2;
public class Test {
public static void main(String[] args) {
Smoking sm = new Teacher();
sm.smoke();
}
}
5.2 接口的特點
接口和類之間的關(guān)系:
類與類之間:繼承關(guān)系,只能單繼承搂捧,不能多繼承盗尸,但是可以多層繼承
類與接口之間:實現(xiàn)關(guān)系队丝,可以單實現(xiàn),也可以多實現(xiàn)
接口與接口之間:繼承關(guān)系,可以單繼承揣云,也可以多繼承
對于一個類來講,他的父類(繼承的關(guān)系)定義的都是:共性內(nèi)容
對于一個類來講收捣,他的父接口(實現(xiàn)的關(guān)系)定義的都是:擴展內(nèi)容
5.3 接口成員的特點
接口不能實例化缀辩,也沒有需要初始化的成員,所以接口中是沒有構(gòu)造方法的