day01-繼承、方法重寫、super關鍵字、this關鍵字、抽象類知識點詳細總結

day01 【複習回顧、繼承、抽象類模板設計模式】

主要內容

1.面向對象回顧
2.封裝(基礎班),繼承(今天),多態(明天+後天)    
3.設計模式:模板設計模式    

第一章 複習

1.1 如何定義類
格式:
	public class 類名{
        //成員變量
        數據類型 成員變量名;
        //成員方法
        public 返回值類型 方法名(參數列表){
            方法體;
            return 返回值;
        }
    }
1.2 如何通過類創建對象
格式:
	類名 對象名 = new 構造方法名(具體參數);
1.3 封裝
  • 封裝的步驟

    a.給成員變量加上private
    b.爲每個成員變量,提供一組getter和setter    
    
  • 封裝的代碼實現

    public class Dog {
        //成員變量
        private int age;
        private String name;
        //提供getter和setter
        //alt+insert 省略...
        //成員方法:吠
        public void bark() {
            System.out.println("小狗嗷嗷叫~~~");
        }
    }
    
    public class TestDog {
        public static void main(String[] args) {
            //創建對象
            Dog dd = new Dog();
            //封裝之後,我們需要通過調用get和set方法來取值或者賦值
            System.out.println(dd.getName());
            System.out.println(dd.getAge());
            //調用方法
            dd.bark();
        }
    }
    
1.4 構造器(構造方法)
  • 構造器的作用

    給創建出的對象的成員變量初始化!!
    
  • 構造器的格式

    格式:
    	public 類名(){
            
        } 
    
    	public 類名(參數列表){
            給對象中成員變量賦值
        }
    
  • 構造器的使用

    無參構造:
    	類名 對象名 = new 構造方法名();
    
    有參構造:
    	類名 對象名 = new 構造方法名(實際參數);
    
    例如:
        Dog dd = new Dog(); //使用無參構造
        Dog dd2 = new Dog(10,"旺財");
    
1.5 this關鍵字
  • this關鍵字代表什麼

    代表當前對象的引用:
    	當前對象,成員方法由哪個對象調用的,方法中的this就代碼那個對象       
    
    
  • this在代碼中的應用

    a.在set方法中使用到this,給同名的成員變量賦值
         public void setAge(int age) {
            this.age = age;
         }
    
    b.在構造方法中使用到this,給同名的成員變量賦值
         public Dog(int age, String name) {
            this.age = age;
            this.name = name;
        }
    
    
1.6 匿名對象
  • 什麼是匿名對象

    沒有名字的對象!!!!
        匿名對象是指只new對象,但是不用對象名來接收
    正常對象:
    	Dog d = new Dog();
    
    匿名對象:
    	new Dog();
    
    注意: 這裏匿名是指沒有使用對象名接收,而不是對象中沒有name屬性    
    
    
  • 匿名對象的使用場景

    當一個對象我們只需要使用一次時就可以選擇使用匿名對象
    public class NiMingDemo {
        public static void main(String[] args) {
            //需求:編寫一個程序,要求用戶輸入他的年齡
            System.out.println("請輸入您的年齡:");
            //使用正常對象
    //        Scanner sc = new Scanner(System.in);
    //        int age = sc.nextInt();//ctrl+alt+v 或者 .var 自動接收方法返回值
            //使用匿名對象
            int age = new Scanner(System.in).nextInt();
            System.out.println("您剛剛輸入的年齡是:" + age);
        }
    }   
    
    

第二章 繼承

  • 引入案例

    假如我們要定義如下類: 學生類,老師類和班主任類,分析如下:
    1. 學生類 屬性:姓名,年齡 行爲:喫飯,睡覺
    2. 老師類 屬性:姓名,年齡,薪水 行爲:喫飯,睡覺,教書
    3. 班主任 屬性:姓名,年齡,薪水 行爲:喫飯,睡覺,管理
        
    如果我們定義三個類,每個類都有姓名,年齡,喫飯,睡覺    
    
    
2.1 繼承的概念
在一個已知類A的基礎上,創建新類B的過程,稱之爲繼承
    
這裏類A,稱爲父類,基類,超類,英文名SuperClass
這裏類B,稱爲子類,派生類,英文名SubClass        

2.2 繼承的格式
格式:
	public class 父類{
     	//成員變量
        //成員方法
    }

	public class 子類 extends 父類{
        子類中就自動繼承了父類中的成員變量和成員方法
        子類也可以添加自己的成員變量和成員方法    
    }

2.3 繼承的案例
父類:人類
    public class Human {
        //人類的共同成員變量和成員方法
        int age;
        String name;

        public void eat(){
            System.out.println("我喫蝙蝠...");
        }

        public void sleep(){
            System.out.println("我聽課睡着了...");
        }
    }

學生類:
    public class Student extends Human{
    }

老師類:
    public class Teacher extends Human {
        //薪水
        double salary;
        //教書
        public void teach(){
            System.out.println("#$%&*($%^*()%&*...");
        }
    }

班主任類:
	public class BanZhuRen extends Human{
        //薪水
        double salary;
        //管理
        public void manager(){
            System.out.println("開播了,趕緊起牀~~~~");
        }
    }
測試類
    public class TestDemo {
        public static void main(String[] args) {
            //1.測試Student類
            Student s1 = new Student();
            System.out.println(s1.age);
            System.out.println(s1.name);
            s1.eat();
            s1.sleep();
            //2.測試Teacher類
            Teacher t1 = new Teacher();
            System.out.println(t1.age);
            System.out.println(t1.salary);
            t1.eat();
            t1.teach();
            //3.班主任類...自己寫完
        }
    }

  • 繼承好處總結

    a.提高代碼的複用性
    b.類與類之間有了關係,爲以後學的"多態"提供了前提   
    
    
2.4 子類不能繼承的內容
a.父類的構造方法子類無法繼承!! (因爲構造方法和類名是一樣的)
b.父類的私有成員,子類可以繼承但是不能直接使用!!!(間接使用)

父類:
	public class Animal {
        private int age;

        public int getAge() {
            return age;
        }

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

        public Animal() {
        }

        public Animal(int age) {
            this.age = age;
        }
	}

子類:
	public class Dog extends Animal {
        //構造方法無法繼承
        //私有成員能繼承,但是子類無法直接訪問

    }

測試類:
	public class TestDog {
    public static void main(String[] args) {
        //1.創建Dog對象
        Dog d = new Dog();
        //2.構造方法無法繼承
        //Dog d1 = new Dog(10); //報錯!!
        //3.私有成員可以繼承,但是無法直接訪問
        //d.age; //錯誤,無法直接訪問
        //比如:
        //古代皇帝,皇帝駕崩了,太子繼位,
        //皇帝江山屬於太子,但是皇帝妃子,太子也繼承了叫額娘,但是不能用!!
        //4.私有成員我們可以間接訪問
        //我們通過 get和set方法,間接訪問私有成員
        d.setAge(10);
        int age = d.getAge();
        System.out.println("獲取到age:"+age);
    }
}
   

2.5 繼承後的特點——成員變量
a.當子父類的成員變量不同名時,訪問成員變量時沒有歧義,寫哪個變量名就是訪問哪個變量
b.當子父類的成員變量同名時,在子類中會根據就近原則,優先訪問子類自己的那個成員變量
c.如果我就想訪問父類的成員變量,能否做到???
    	可以,在子類的方法中,使用super.變量名,就會訪問父類中那個成員變量!
    
/**
 * 父類
 */
public class Fu {
//    int numFu = 10;
    int num = 10;
}
    
/**
 * 子類
 */
public class Zi extends Fu{
//    int numZi = 99;
    int num = 99;
    //展示
    public void show() {
        //子父類成員變量不同名
//        System.out.println(numZi); // 99
//        System.out.println(numFu); // 10
        //子父類成員變量同名
        //就近原則,優先訪問子類自己的成員變量
        System.out.println(num); // 99

        //如果就想訪問父類的num能否做到??
        //使用Java提供的另外一個關鍵字
        System.out.println(super.num); //10
    }
}  

public class TestDemo {
    public static void main(String[] args) {
        //1.創建Zi對象
        Zi zz = new Zi();
        //2.調用方法
        zz.show();
    }
}

2.6 繼承後的特點——成員方法[重點]
a.當子父類的成員方法不同名時,調用成員方法時沒有歧義,寫哪個方法名就是調用哪個方法
b.當子父類的成員方法同名時,使用子類對象調用該方法,根據就近原則,優先調用子類自己的那個成員方法  
c.如果我就想通過子類對象,調用父類中的那個同名方法,能做到嗎???
    	不能做到!!
    	但是可以在子類的方法中,使用super.方法名()調用父類那個同名方法!!!
    
/**
 * 父類
 */
public class Fu {
//    public void showFu() {
//        System.out.println("Fu類的show....");
//    }

    public void show() {
        System.out.println("Fu類的show....");
    }
}

/**
 * 子類
 */
public class Zi extends Fu {

//    public void showZi(){
//        System.out.println("Zi類的show...");
//    }

    public void show(){
        //在子類中可以使用super
        System.out.println("Zi類的show...");
        super.show();
    }
}

public class TestDemo {
    public static void main(String[] args) {
        //1.創建子類對象
        Zi zz = new Zi();
        //2.調用方法
        //子父類成員方法不同名
//        zz.showZi(); //Zi類的show...
//        zz.showFu(); // Fu類的show....
        //子父類成員方法同名
        //就近原則,優先子類自己的show方法
        zz.show(); // Zi類的show...
        //無法做到直接通過子類對象,super去調用父類的同名方法
        //zz.super.show(); //報錯!!!因爲在測試類使用super,並不是Fu類,而是指測試類的父類
        //可以在子類的show方法中,使用super.show()調用父類的同名方法
        //記住: super關鍵字只能在子類內部使用
    }
}

2.7 重寫的概念和應用
方法的重載(overload):
	在同一個類中,出現了方法名一樣,但是參數列表(參數個數|參數類型|參數順序)不一樣的各種方法,稱爲方法的重載
方法的重寫(override):
	在繼承關係中,子類中出現了一個和父類除了方法體,其他一模一樣的方法,稱爲方法的重寫     
  
方法重寫的具體應用:        
	子類繼承父類時,會繼承父類的成員方法,那麼當子類發現繼承過來的方法功能不足或者不適用時,子類就可以重寫該方法,重新實現自己需要的方法體即可  

/**
 * 動物類
 */
public class Animal {

    public void eat(){
        System.out.println("動物在喫");
    }

    public void sleep(){
        System.out.println("動物在睡");
    }
}

/**
 * 狗類
 */
public class Dog extends Animal{
    //當子類繼承父類的方法後,發現父類的方法功能不足或者不適用,我們可以重寫
    public void eat(){
        System.out.println("狗狗舔着喫...");
    }

    public void sleep(){
        System.out.println("狗狗趴着睡...");
    }
}      

2.8 @Override註解
@Xxxx 這種東西,我們稱爲註解,英文名Annotation
@Override  此註解叫做方法重寫註解,
			主要作用就是檢查重寫的方法是否格式正確(和父類的除了方法體一模一樣)  

/**
 * 動物類
 */
public class Animal {

    public void eat(){
        System.out.println("動物在喫");
    }

    public void sleep(){
        System.out.println("動物在睡");
    }
}

/**
 * 狗類
 */
public class Dog extends Animal{
    //當子類繼承父類的方法後,發現父類的方法功能不足或者不適用,我們可以重寫
    @Override //加上此註解,可以幫助我們檢測eat方法重寫的是否正確
    public void eat(){
        System.out.println("狗狗舔着喫...");
    }
    @Override //加上此註解,可以幫助我們檢測eat方法重寫的是否正確
    public void sleep(){
        System.out.println("狗狗趴着睡...");
    }
}
                

2.9 方法重寫的注意事項
a.方法重寫是發生在子父類之間的關係
b.子類方法重寫父類方法,必須要保證權限大於等於父類權限(一般來說,父類方法寫啥權限,子類也寫啥權限)
    		Java中有四大權限,從大到小依次爲:
			public protected 不寫(默認|default) private
c.方法重寫,除了方法體其他的都要和父類一模一樣(雖然權限可以不一樣,但是一般我們也寫一樣的權限)            

2.10 繼承後的特點——構造方法
  • 構造方法特點介紹

    a.子類能否繼承父類的構造方法??
        	子類是無法繼承父類的構造方法   
    b.在子類的"任何構造方法""第一行",都有默認一句代碼"super()",代表調用父類的無參構造    
    
    
  • 構造方法案例演示

    /**
     * 父類
     */
    public class Person {
        int age;
        String name;
    
        public Person() {
            System.out.println("Person的無參構造...");
        }
    }
    
    
    /**
     * 子類
     */
    public class Worker extends Person {
        //工資
        double salary;
    
        //構造方法
        public Worker(){
            //默認有一句代碼 super();
            System.out.println("Worker的構造方法");
        }
    
        public Worker(double salary){
            //默認有一句代碼 super();
            this.salary = salary;
            System.out.println("Worker的salary構造方法");
        }
    
    }
    
    public class TestDemo {
        public static void main(String[] args) {
            //1.創建Worker對象
    //        Worker w = new Worker(); // 調用子類無參構造,子類無參構造中調用父類的無參構造
            Worker w = new Worker(3000); // 調用子類有參構造,子類有參構造中調用父類的無參構造
        }
    }
    
    
  • 構造方法總結

    a.子類的任何構造,第一行都會調用父類的無參構造
    b.子類的構造方法第一行,super是默認存在的,可以省略不寫,但是不寫不代表沒有!!!    
    
    
2.11 super(參數)和this(參數)
  • 案例引入

    /**
     * 父類
     */
    public class Person {
        int age;
        String name;
    
        public Person() {
            System.out.println("Person的無參構造...");
        }
    
        public Person(int age, String name) {
            this.age = age;
            this.name = name;
            System.out.println("Person有參構造");
        }
    }
    
    /**
     * 子類
     */
    public class Worker extends Person {
        //工資
        double salary;
    
        //構造方法
        public Worker(){
            //默認有一句代碼 super();
            System.out.println("Worker的構造方法");
        }
    
        public Worker(double salary){
            //默認有一句代碼 super();
            this.salary = salary;
            System.out.println("Worker的salary構造方法");
        }
    
        //子類的構造中默認第一行調用父類無參構造
        //但是我們可以手動修改super()代碼,讓他調用有參構造
        public Worker(int age,String name,double salary){
            //調用父類的有參構造
            super(age,name);
            this.salary = salary;
        }
    }
    
    public class TestDemo {
        public static void main(String[] args) {
            //1.創建Worker對象
            Worker w = new Worker(20,"小王吧",4000);
            //2.打印對象中屬性值
            System.out.println(w.name);
            System.out.println(w.age);
            System.out.println(w.salary);
        }
    }
    
    
  • super(…)用法演示

    super() 代表調用父類的無參構造,默認的
    super(參數) 代表調用父類的有參構造,具體調用哪個有參構造根據參數來決定   
    
    
  • super(…)案例圖解

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-f8iRHAMy-1583144789620)(img/image-20200302143555121.png)]

  • this(…)用法演示

    this(參數):
    	在本類的構造方法中調用本類的其他構造
            
    public class Dog {
        int age;
        String name;
    
        public Dog() {
            //在本類的構造方法中
            this(10,"來福");
            //調用本類的另外一個構造
        }
    
        public Dog(int age, String name) {
            this.age = age;
            this.name = name;
        }
    }
    
    注意: this(參數)也必須寫在構造方法的第一行,所以this(參數)super(參數)他們只能出現一個       
    
    
  • 小結

    a.子類的構造方法中默認有一句super()調用父類無參構造,我們可以手動改寫super(參數)調用父類的有參構造,
    具體是哪個有參構造,由參數決定
    b.super(...)this(...) 必須在第一行,所有不能同時出現
    c.super(..)this(..)調用父類的構造和子類自己的其他構造,具體哪個構造由參數決定
    d.super(..) 調用父類的有參構造,初始化父類繼承的成員變量
    e.this(..) 調用子類的其他構造方法    
    
    
2.12 Java中繼承的特點
1. Java只支持單繼承,不支持多繼承。(一個類最多隻有一個親爹)
2. 一個類可以有多個子類。(一個類可以有多個孩子)     
3. 可以多層繼承(一個類可以有父類,其父類也有父類)
總結:  Java只支持單繼承,但是支持多層繼承  

第三章 抽象類

3.1 抽象類的概念和引入
a.抽象方法: 只有方法的聲明,沒有方法的實現
b.含有抽象方法的類就是一個抽象類    

3.2 abstract使用格式
  • 抽象方法

    public  abstract 返回值類 方法名(參數列表);
    
    
  • 抽象類

    public abstract class 類名{
        抽象方法
        正常方法    
    }
    
    
  • 抽象類的使用

    //抽象類:動物
    public abstract class Animal {
        //抽象方法:跑
        public abstract void run();
    }
    
    注意:抽象類是不能創建對象的,天生就是做父類的! 給其他子類繼承的!!!
    
    抽象類不能創建對象,需要有子類繼承它,並且重寫所有抽象方法之後,該子類才能創建對象
        
    //抽象類:動物
    public abstract class Animal {
        //抽象方法:跑
        public abstract void run();
    }
    
    /**
     * 抽象類的子類貓
     */
    public class Cat extends Animal {
        //a.給Cat也加上abstract
        //b.重寫抽象類中所有的抽象方法
        @Override
        public void run() {
            System.out.println("貓在屋頂上跑...");
        }
    }
    
    public static void main(String[] args) {
        //1.創建Animal的對象
        //Animal an = new Animal(); // Java規定抽象類不能創建對象
        //2.創建Animal的子類Cat對象
        Cat cc = new Cat();
        cc.run();
    }    
    
    
3.3 抽象類的特徵和注意事項
抽象類的特徵:
	有得有失!! 
  有得: 抽象類具備了含有抽象方法的能力
  有失: 失去創建對象的能力    
        
注意事項:
	a.抽象類不能創建對象(Java規定的!!)
    b.抽象類是有構造方法的,用於初始化類的成員變量
    c.抽象類中不一定有抽象方法,但是含有抽象方法的類一定是抽象類(一般來說抽象類中是有抽象方法)
    d.抽象類的子類必須重寫抽象類的所有抽象方法,否則子類還是一個抽象類
    e.抽象類的天生作用就是做父類,爲子類提供模板    

3.4 抽象類存在的意義
抽象類的天生作用就是做父類,爲子類提供模板   

3.5 第一個設計模式:模板模式(司機開車)
司機開車:
		開門,點火,開車,熄火,關門
新司機:
		開門,點火,兩隻手全是汗緊握方向盤,熄火,關門
老司機:            
        開門,點火,一隻手接電話,一隻手抽着煙,偶爾手指點點,熄火,關門   
            

/**
 * 司機類,父類,模板
 */
public abstract class Driver {
    //開車
    public void drive(){
        System.out.println("開門...");
        System.out.println("點火...");
        kai();
        System.out.println("熄火...");
        System.out.println("關門...");
    }
    ////新司機: 兩隻手全是汗緊握方向盤
    ////老司機: 一隻手接電話,一隻手抽着煙,偶爾手指點點
    public abstract void kai();
}

/**
 * 新司機
 */
public class NewDriver extends Driver {
    @Override
    public void kai() {
        System.out.println("兩隻手全是汗緊握方向盤,慢慢開車..");
    }
}

/**
 * 老司機
 */
public class OldDriver extends Driver {
    @Override
    public void kai() {
        System.out.println("一隻手接電話,一隻手抽着煙,偶爾手指點點,biu一下過去了..");
    }
}
//測試類
public class TestDemo {
    public static void main(String[] args) {
        //1.新司機
        NewDriver nd = new NewDriver();
        nd.drive();
        //2.老司機
        OldDriver od = new OldDriver();
        od.drive();
    }
}

            

總結
繼承:

a.繼承的格式
    	public class 子類 extends 父類{
            
        }
b.不能繼承的內容
    	i.構造方法子類不能繼承
    	ii.私有成員子類可以繼承但是不能直接使用(間接使用,通過get/set方法使用)
c.繼承後成員變量和成員方法的特點:
		i.不同名,沒有歧義
        ii.同名時在子類中優先調用子類自己的成員   
        iii.我們可以使用關鍵字
            	super.變量名 訪問父類的同名成員變量
            	super.方法名() 調用父類的同名成員方法
d.方法的重寫
       方法的重寫:在繼承關係中,子類有一個和父類除了方法體其他一模一樣的方法,該方法稱爲重寫的方法
       什麼時候需要重寫:
				當子類繼承父類的方法後,發現父類的方法適用,那麼子類就可以重寫該方法
                重寫時可以使用@override幫助我們檢測是否重寫格式正確
e.super(..)
        用於子類的構造方法第一行,調用父類的構造方法,具體是哪一個構造
                    由super(參數)中的參數決定
f.this(..)                    
       用於本類的構造方法第一行,調用本類的其他構造方法,具體是哪一個構造
                    由this(...)中的參數決定
g.Java繼承的特點:
		只支持單繼承,但是支持多層繼承
            
抽象類:
	a.抽象方法格式: public abstract void 方法();
    	抽象類格式:  public abstract class 抽象類名{ 可能有抽象方法,也可以沒有抽象方法}   
	b.抽象類怎麼用?
        使用子類繼承抽象類,重寫所有抽象方法後,子類才能創建對象
    c.抽象類的意義:
		給子類繼承的,爲子類提供的模板(模板設計模式)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章