1. 程式人生 > >java學習筆記(12-繼承、抽象類)

java學習筆記(12-繼承、抽象類)

1.繼承關鍵字extends

java中繼承特點:

  • 在Java中,類只支援單繼承,不允許多繼承,也就是說一個類只能有一個直接父類
  • 多個類可以繼承一個父類
  • 在Java中,多層繼承是可以的,即一個類的父類可以再去繼承另外的父類,例如C類繼承自B類,而B類又可以去繼承A類,這時,C類也可稱作A類的子類
  • 子類只能獲取父類非私有成員
  • super:可以獲取父類的成員變數和成員方法,用法和this是相似的
package com.daigua12;

public class ExtendsDemo {
    public static void main(String[] args) {
        Dota1 d = new Dota1();
        d.start();
        d.stop();
        
        Lol1 l = new Lol1();
        l.start();
        l.stop();
    }
}

class Game {
    String name;
    double version;
    String agent;
    
    public static void start() {
        System.out.println("遊戲啟動了!");
    }
    public static void stop() {
        System.out.println("遊戲停止了!");
    }
    
}

class Dota1 extends Game{
    
}

class Lol1 extends Game{
    
}

2.訪問變數的順序

package com.daigua12;

/*
 * 繼承中成員變數的特點
 *      子類只能獲取父類非私有成員
 *      子父類中成員變數的名字不一樣直接獲取父類的成員變數
 *      子父類中成員變數名字是一樣的獲取的是子類的成員變數
 * 
 * 就近原則:誰離我近我就用誰
 *      如果有區域性變數就使用區域性變數
 *      如果沒有區域性變數,有子類的成員變數就使用子類的成員變數
 *      如果沒有區域性變數和子類的成員變數,有父類的成員變數就使用父類的成員變數
 *      啥都沒有,出錯了!!!
 * 
 * super:可以獲取父類的成員變數和成員方法,用法和this是相似的
 */
public class ExtendsDemo3 {
    public static void main(String[] args) {
        Kid3 k = new Kid3();
        k.show();
    }
}

class Dad3 {
    String name = "建霖";
}

class Kid3 extends Dad3 {
    String name = "四蔥";
    
    public void show() {
        String name = "五蔥";
        
        System.out.println(super.name);
        System.out.println(this.name);
        System.out.println(name);
    }
}

3.方法重寫

package com.daigua12;

/*
 *  方法重寫的應用場景:當父類的方法不能完全滿足子類使用,這個時候子類重寫父類的方法,
 *                  並可以在方法中使用關鍵字super呼叫父類的方法,這樣做即可以保有父類的功能,也可以擁有子類特有的功能
 *  方法重寫的注意事項:
 *                不能重寫父類私有的方法
 *               許可權必須大於等於父類方法的許可權
 *  
 *  註解:@
 *  
 */
public class ExtendsDemo5 {
    public static void main(String[] args) {
        NewPhone np = new NewPhone();
        np.call();
    }
}

class Phone {
    void call() {
        System.out.println("打電話");
    }
}

class NewPhone extends Phone {

    @Override
    public void call() {
        super.call();
        System.out.println("錄音");
        // System.out.println("打電話");

        // super.call();
    }
}

4.構造方法呼叫順序

package com.daigua12;

/*
* 繼承中構造方法的執行順序
*           在子父類中,建立子類物件,呼叫子類的構造方法,
*           在子類的構造方法的第一行程式碼如果沒有呼叫父類的構造或者沒有呼叫子類的其他構造,則預設呼叫父類無參構造
* 為什麼要呼叫父類構造?
*           因為需要給父類的成員變數初始化
* 肯定會先把父類的構造執行完畢,在去執行子類構造中的其他程式碼
* 
* 我是父類無參構造 --- 我是子類有參構造 --- 我是子類無參構造
*/
public class ExtendsDemo6 {
    public static void main(String[] args) {
        // Die d = new Die();
        Zi6 z = new Zi6();
    }
}

class Die6 {
    public Die6() {
        System.out.println("我是父類無參構造");
    }

    public Die6(int num) {
        System.out.println("我是父類有參構造");
    }
}

class Zi6 extends Die6 {
    public Zi6() {
        // super(1);
        // super();

        this(1);// 不會再呼叫父類的無參構造了

        System.out.println("我是子類無參構造");
    }

    public Zi6(int num) {
        // 會預設呼叫父類無參構造
        System.out.println("我是子類有參構造");
    }
}

5.抽象類

package com.daigua12;

public class AbstractDemo {
    public static void main(String[] args) {
        Cat c = new Cat();
        c.eat();
    }
}

// 抽象類,一般作為基類
abstract class Animal {
    public abstract void eat();

    // 非抽象方法,子類可以不用重寫
    public void run() {
        System.out.println("running");
    }
}

class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("小貓吃魚!");
    }

}

6.抽象類成員特點

package com.daigua12;

/*
 * 抽象類的成員特點:
 *      成員變數
 *          可以有成員變數
 *          可以有常量
 *      成員方法
 *          可以有抽象方法
 *          可以有非抽象方法
 *      構造方法
 *          可以有構造方法的,需要對抽象類的成員變數進行初始化
 * 
 * final:修飾類、成員變數、成員方法
 */
public class AbstractDemo3 {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.barking();
    }
}

abstract class Animal2 {
    String name = "哮天犬";
    // final變數只能初始化一次
    final int num = 10;

    public Animal2() {
        System.out.println("我是抽象類的構造方法");
    }

    public abstract void eat();

    public void run() {
    }
}

class Dog extends Animal2 {
    public void barking() {
        System.out.println(name);
        System.out.println(num);
    }

    @Override
    public void eat() {
        // TODO Auto-generated method stub

    }
}

7.抽象類案例1-老師

要求:
    老師類:
        屬性:姓名,年齡,性別
        行為:講課
    基礎班老師:
        屬性:姓名,年齡,性別
        行為:講基礎班課程
    就業班老師:
        屬性:姓名,年齡,性別
        行為:講就業班課程
package com.daigua12;

/*
 * 老師類:
    屬性:姓名,年齡,性別
    行為:講課
 基礎班老師:
屬性:姓名,年齡,性別
    行為:講基礎班課程
     就業班老師:
屬性:姓名,年齡,性別
        行為:講就業班課程
 * */
public class AbstractTeacher {
    public static void main(String[] args) {
        BasicTeacher b1 = new BasicTeacher("魯迅", 18, "男");
        b1.action();

        WorkTeacher w1 = new WorkTeacher("菩提老祖", 1008, "未知");
        w1.action();

    }
}

abstract class Teacher {
    String name;
    int age;
    String gender;

    public Teacher(String name, int age, String gender) {
        this.age = age;
        this.gender = gender;
        this.name = name;
    }

    public abstract void action();

}

class BasicTeacher extends Teacher {

    public BasicTeacher(String name, int age, String gender) {
        // TODO Auto-generated constructor stub
        super(name, age, gender);
    }

    @Override
    public void action() {
        // TODO Auto-generated method stub
        System.out.println("講基礎班課程");
    }

}

class WorkTeacher extends Teacher {
    public WorkTeacher(String name, int age, String gender) {
        // TODO Auto-generated constructor stub
        super(name, age, gender);
    }

    @Override
    public void action() {
        // TODO Auto-generated method stub
        System.out.println("講就業班課程");
    }
}

8.抽象類的細節問題

 A:抽象類關鍵字abstract可以和哪些關鍵字共存?
    1.private:
    私有的方法子類是無法繼承到的,也不存在覆蓋,而abstract和private一起使用修飾方法,abstract既要子類去實現這個方法,而private修飾子類根本無法得到父類這個方法。互相矛盾。
    2.final: 
    抽象類不能和final共存,因為抽象類自身無法建立物件,我們需要通過子類建立物件,一旦抽象類使用final關鍵字,那麼抽象類就沒有子類
    抽象方法不能和final共存,因為抽象方法後期需要被子類重寫,一旦加final無法重寫   
    3.static:
    抽象方法不能和static關鍵字共存,因為一旦加static我們就可以通過類名直接訪問抽象方法,由於抽象方法沒有方法體,沒有任何意義,也不允許這樣做
 B:抽象類中是否可以不定義抽象方法?
    是可以的,那這個抽象類的存在到底有什麼意義呢?不讓該類建立物件,方法可以直接讓子類去使用
 C:抽象類是否有建構函式?
    有,抽象類的建構函式,是由子類的super語句來呼叫,用於給抽象類中的成員初始化