天天看點

Java學習路線-5:繼承第12 章 : 繼承的定義與使用

第12 章 : 繼承的定義與使用

59 繼承問題引出

繼承:擴充已有類的功能

60 繼承的實作

class 子類 extends 父類      

子類:派生類

父類:超類

繼承實作的主要目的

子類可以重用父類中的結構,并且擴充功能

class Person{
    private String name ;
    private int age ;

    public void setName(String name){
        this.name = name ;
    }

    public void setAge(int age){
        this.age = age ;
    }

    public String getName(){
        return this.name ;
    }

    public int getAge(){
        return this.age ;
    }

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

}


class Student extends Person{
    String school ;

    public void setSchool(String school){
        this.school = school ;
    }
    
    public String getSchool(){
        return this.school ;
    }

    public Student(String name, int age, String school){
        super(name, age);
        this.school = school ;
    }
}

class Demo{
    public static void main(String[] args) {
        Student student = new Student("張三" , 23, "大學");
        
        System.out.println(student.getName());
        // 張三

        System.out.println(student.getSchool());
        // 大學
    }
}
      

61 子類對象執行個體化流程

子類執行個體化會自動調用父類構造方法

預設執行 super()

子類構造方法預設調用父類無參構造方法,隻允許放在子類構造方法首行

結論:

定義類的時候最好寫無參構造方法

執行個體化子類對象的同僚一定會執行個體化父類對象

class Person{
    private String name ;
    private int age ;
    
    public Person(){}

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

}


class Student extends Person{
    public Student(String name, int age){
        super(name, age); // 調用父類構造方法
    }
}

class Demo{
    public static void main(String[] args) {
        Student student = new Student("張三" , 23);
    }
}
      

super, this 兩個語句不能同時出現

相同點:

1、都可以調用構造方法

2、都隻能放在構造方法首行

不同點:

1、super 調用父類構造方法

2、this 調用本類構造方法

62 繼承定義限制

Java不允許多重繼承,隻允許多層繼承

多重繼承

class A{}
class B{}
class C extends A, B{}      

多層繼承, 一脈傳承

class A{}
class B extends A{}
class C extends B{}      

繼承關系最好不要超過三層

子類可以繼承父類中所有操作結構

顯式繼承非私有操作

隐式繼承私有操作

class Person{
    private String name ;
    
    public String getName(){
        return this.name ;
    }

    public Person(){}

    public Person(String name){
        this.name = name ;
    }
}


class Student extends Person{
    public void fun(){
        // 錯誤, 子類不能通路父類中的私有屬性
        // System.out.println(this.name); 

        // 子類間接通路父類中的私有屬性
        System.out.println(this.getName());  
        // 張三
    }

    public Student(String name){
        super(name);
    }
}

class Demo {
     public static void main(String[] args) {
        Student student = new Student("張三");
        student.fun();
    }
}
      

63 方法覆寫

覆寫意義:優化功能

子類調用父類方法

super.方法()

調用本類方法, this可省略

this.方法()

class Resource{
    public void connect(){
        System.out.println("資源連接配接");
    } 
}


class Database{
    public void connect(){
        System.out.println("資料庫資源連接配接");
    }

}


class Demo{
    public static void main(String[] args) {
        Database db = new Database();
        
        // 調用子類的方法
        db.connect();  
        // 資料庫資源連接配接
    }
}

      

64 方法覆寫限制

覆寫的方法通路控制權限要 大于等于 父類方法控制權限

通路權限控制

public > default(不寫) > private

差別Override Overloading

Override 覆寫

概念:方法名,簽名(參數類型,個數),傳回值相同

權限:被覆寫的方法不能有更嚴格的權限控制

範圍:發生在繼承關系中

Overloading 重載

概念:方法名相同,簽名(參數類型,個數)不同,推薦傳回類型一緻

權限:沒有權限控制

範圍:發生在一個類中

65 屬性覆寫

屬性覆寫:子類定義了與父類相同名稱的成員

差別:this super

this 先查找本類,再查找父類,this可以表示本類對象

super 直接查找父類

class Father{
    private String name = "Father" ;

}

class Child{
    private String name = "Child" ;
    
    public String getName(){
        return this.name;
    }
}

class Demo{
    public static void main(String[] args) {
        Child child = new Child();
        System.out.println(child.getName()) ;
        // Child
    }
    
}      

66 final關鍵字

final 定義不能被繼承的類,不能被覆寫的方法,常量

final class Demo{}  // 不能有子類

class Demo{
    public final void fun(){}  // 不能被覆寫
} 

class Demo{
    private final int ON = 1 ;  // 常量不能被重新指派
    private final int OFF = 0 ; 
}       

常量往往都是公共的,全局常量

public static final int ON = 1 ;
public static final int OFF = 0 ;       

常量每個字元都必須大寫

67 案例分析一(學生類)

簡單Java類

學生類繼承人類

人類

-四個屬性:name,address, sex, age

-三個構造:四參,兩參,無參

-一個方法:顯示輸出

學生

-增加兩個屬性:math,english

-三個構造:六參,兩餐,無參

-一個重寫方法:顯示輸出

class Person{
    private String name ;
    private int age ;
    private String address;
    private char sex;

    public void setName(String name){
        this.name = name ;
    }

    public void setAge(int age){
        this.age = age ;
    }

    public void setAddress(String address){
        this.address = address ;
    }

    public void setSex(char sex){
        this.sex = sex ;
    }

    public String getName(){
        return this.name ;
    }

    public int getAge(){
        return this.age ;
    }

    public String getAddress(){
        return this.address ;
    }

     public char getSex(){
        return this.sex ;
    }

    public Person(){}

    public Person(String name, int age){
        // 調用本類構造方法
        this(name, age, "", '男');
    }

    public Person(String name, int age, String address, char sex){
        this.name = name ;
        this.age = age ;
        this.address = address ;
        this.sex = sex ;
    }

    public String getInfo(){
        return "name: " + this.name + 
                " age: " + this.age +
                " address: " + this.address + 
                " sex: " + this.sex ;
    }
}


// 繼承
class Student extends Person{
    private double math ;
    private double english ;

    public void setMath(double math){
        this.math = math ;
    }

    public void setEnglish(double english){
        this.english = english ;
    }
    
    public double getMath(){
        return this.math ;
    }

     public double getEnglish(){
        return this.english ;
    }

    // 重載構造方法
    public Student(){}


    public Student(String name, int age){
        // 調用父類構造方法
        super(name, age);
    }

    public Student(String name, int age, String address, char sex, 
        double math, double english){
        super(name, age, address, sex);
        this.math = math ;
        this.english = english ;
    }

    // 覆寫父類方法
    public String getInfo(){
        return super.getInfo() + 
                " math: " + this.math +
                " english: " + this.english ;
    }
}

class Demo{
    public static void main(String[] args) {
        Student student = new Student("張三", 16, "北京", '男', 99.9, 87.9);
        System.out.println(student.getInfo());
        // name: 張三 age: 16 address: 北京 sex: 男 math: 99.9 english: 87.9

    }
}
      

68 案例分析二(管理人員與職員)

員工類

-2個屬性 name, age

-2個構造 無參, 2參

-1個方法 顯示資訊

普通職員

-4屬性 name, age, dept, salary

-2構造 無參, 4參

管理人員

-4屬性 name, age, position, income

class Employee{
    private String name ;
    private int age ;

    public Employee(){}

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

    public String getInfo(){
        return "name: " + this.name + " age: " + this.age ;
    }
}


class Stuff extends Employee{
    private String dept ;
    private double salary ;

    public Stuff(){}

    public Stuff(String name, int age, String dept, double salary){
        super(name, age);
        this.dept = dept ;
        this.salary = salary ;
    }

    public String getInfo(){
        return "【Stuff】 " + super.getInfo() + 
            " dept: " + this.dept + 
            " salary: " + this.salary;
    }
}


class Manager extends Employee{
    private String position ;
    private double income ;

    public Manager(){}

    public Manager(String name, int age, String position, double income){
        super(name, age);
        this.position = position ;
        this.income = income ;
    }

    public String getInfo(){
        return "【Manager】 " + super.getInfo() + 
            " position: " + this.position + 
            " income: " + this.income;
    }
}

class Demo{
    public static void main(String[] args) {
        Stuff stuff = new Stuff("張三", 23, "技術部", 3000.0);
        Manager manager = new Manager("李四", 32, "技術總監", 150000.0);

        System.out.println(manager.getInfo());
        // 【Manager】 name: 李四 age: 32 position: 技術總監 income: 150000.0

        System.out.println(stuff.getInfo());
        // 【Stuff】 name: 張三 age: 23 dept: 技術部 salary: 3000.0

    }
}

      

69 案例分析三(字元串統計)

統計 字元o 和 n 出現的次數 do you know?

方式一:傳回數組

class CountDemo{
    // 統計兩個字元個數,第一個為o, 第二個為u
    public static int[] getCount(String str){
        int[] countData = new int[2] ;

        char[] data = str.toCharArray() ;
        

        for(char c : data){
            if(c == 'o' || c == 'O'){
                countData[0] ++;
            }
            else if(c == 'u' || c == 'U'){
                countData[1] ++;
            }
        }
        
        return countData;
    }

    public static void main(String[] args) {
        int[] countData = CountDemo.getCount("are you ok?") ;
        
        System.out.println("o: " + countData[0]); // o: 2
        System.out.println("u: " + countData[1]); // u: 1
    }
}      

方式二:傳回對象

class StringUtil{
    private String content ; 

    public StringUtil(String content){
        this.content = content ;
    }

    public String getContent(){
        return this.content ;
    }
}


class CountDemo extends StringUtil {
    private int oCount = 0;
    private int uCount = 0;

    public CountDemo(String content){
        super(content) ;

        this.countChar() ;  //構造方法調用統計
    }

    // 統計兩個字元個數
    public void countChar(){
    
        char[] data = super.getContent().toCharArray() ;
        
        for(char c : data){
            if(c == 'o' || c == 'O'){
                this.oCount ++;
            }
            else if(c == 'u' || c == 'U'){
                this.uCount ++;
            }
        }
    }

    public int getOCount(){
        return this.oCount ;
    }

     public int getUCount(){
        return this.uCount ;
    }

}

class Demo{
    public static void main(String[] args) {
        CountDemo countData = new CountDemo("are you ok?") ;
        
        System.out.println("o: " + countData.getOCount()); // o: 2
        System.out.println("u: " + countData.getUCount()); // u: 1
    }
}      

70 案例分析四(數組操作)

1、實作數組儲存資料

(1)大小由外部決定

(2)增加資料,滿了則失敗

(3)數組擴容

(4)取得數組全部資料

2、實作兩個派生類

(1)數組排序

(2)數組反轉

如果子類方法和父類方法功能相同,優先考慮覆寫父類方法

class ArrayDemo{
    private int point = 0;
    private int[] data = null;

    public ArrayDemo(int length){
        // 傳入的長度如果小于1則等于1
        if(length < 1){
            length = 1;
        }

        // 開辟數組空間
        this.data = new int[length];

    }

    // 添加元素
    public boolean add(int element){

        if(this.point < this.data.length){
            this.data[this.point] = element ;
            this.point ++ ;
            return  true;
        }
        else{
            return  false;    
        }
    }

    // 數組擴容
    public void increment(int num){

        // 數組一旦确定大小就不能被改變
        int[] newData = new int[data.length + num];
        // arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
        System.arraycopy(this.data, 0, newData, 0, this.data.length);

        //修改數組引用
        this.data = newData ;
    }

    public int[] getData(){
        return this.data ;
    }

    public void printData(){
        System.out.print("{");
        for(int i : this.getData()){
            System.out.print(i);
            System.out.print(", ");
        }
        System.out.println("}");
    }
}


// 排序數組
class SortArray extends ArrayDemo{
    public SortArray(int length){
        super(length);
    }

    public int[] getData(){
        java.util.Arrays.sort(super.getData());
        return super.getData();
    }
}


// 反轉數組
class ReverseArray extends ArrayDemo{
    public ReverseArray(int length){
        super(length);
    }

    public int[] getData(){
        int center = super.getData().length / 2;
        int head = 0 ;
        int tail = super.getData().length - 1;
        
        for(int i = 0 ; i < center ; i++){
            int temp =  super.getData()[head] ;
            super.getData()[head] = super.getData()[tail] ; 
            super.getData()[tail]  = temp ;

            head ++ ;
            tail -- ;
        } 

        return super.getData();
    }
}

class Demo{
    public static void main(String[] args) {
        ArrayDemo array = new ArrayDemo(3);

        System.out.println(array.add(1)); // true
        System.out.println(array.add(2)); // true
        System.out.println(array.add(3)); // true

        System.out.println(array.add(4)); // false
        System.out.println(array.add(5)); // false

        array.increment(3) ; 

        System.out.println(array.add(6)); // true
        System.out.println(array.add(7)); // true

        array.printData();
        // {1, 2, 3, 6, 7, 0, }


        // 排序數組
        SortArray sortArray = new SortArray(5);
        sortArray.add(2);
        sortArray.add(6);
        sortArray.add(3);
        sortArray.add(5);
        sortArray.printData();
        // {0, 2, 3, 5, 6, }    


        // 反轉數組
        ReverseArray reverseArray = new ReverseArray(5) ;
        reverseArray.add(1) ;
        reverseArray.add(2) ;
        reverseArray.add(3) ;
        reverseArray.add(4) ;
        reverseArray.add(5) ;
        reverseArray.printData() ;
        // {5, 4, 3, 2, 1, }

    }
}