java自學(xué)第3期——繼承、多態(tài)、接口、抽象類、final關(guān)鍵字、權(quán)限修飾符、內(nèi)部類

一.繼承:

關(guān)鍵字extends

/*
定義一個父類:人類
定義父類格式:public class 父類名稱{
}
定義子類格式:public class 子類名稱 extends 父類名稱{
}
*/

  • 代碼示范:

    *
    在這里插入圖片描述

    要點:
    1.子類中在main方法中創(chuàng)建父類對象可調(diào)用父類方法;
    2.不加關(guān)鍵字直接訪問本方法局部變量(可重名時區(qū)分);
    3.使用this關(guān)鍵字訪問本類成員變量(可重名時區(qū)分);
    4.使用super關(guān)鍵字訪問父類成員變量(可重名時區(qū)分);
    5.如果存在方法的重名:父類與子類有重名方法:
    ——對象new的誰則優(yōu)先調(diào)用誰的重名方法,沒有則向上尋找;
    前面介紹了成員變量、成員方法繼承的訪問特點,接下來是構(gòu)造方法:
    ——子類構(gòu)造方法(父類無參時)中有一個默認(rèn)贈送的super()方法
    ——父類有參時,子類里調(diào)用super的()里傳參,重載時誰對的上調(diào)用誰;
    6.如果要更新修改父類方法,本著設(shè)計原則盡量不去直接修改正在使用的類,
    則可以進(jìn)行覆蓋重寫:格式:通過使用super關(guān)鍵字繼承父類需要的方法。

@Override
方法外部相同(){
   super.父類方法();
   //這里添加新的內(nèi)容
}
/*
小結(jié)super
super關(guān)鍵字作用:
示例:
   public class demo06Super extends demo01people {

   public void method1(){
       System.out.println(super.num);   //1.在子類成員方法中訪問父類的成員變量
   }
   public void method2(){
       super.methodChongMing(); // 2.在子類成員方法中訪問父類的成員方法
   }
   public demo06Super(){
       super(); //3.在子類的構(gòu)造方法中訪問父類的構(gòu)造方法
   }
}
*/

7.this關(guān)鍵字的作用小結(jié):

this關(guān)鍵字的作用:
1.在本類的成員方法中訪問本類的成員變量
2.在本類成員方法中訪問本類的另一個成員方法
3.在本類的構(gòu)造方法中訪問本類的另一個構(gòu)造方法:
(1)this(...)調(diào)用必須是構(gòu)造方法的第一個語句,一個this;
(2)super和this兩種構(gòu)造調(diào)用不能同時使用

  • 代碼示范:
String name = "python";
public void method1(){
        String name = "python";
        System.out.println(name);//無關(guān)鍵字時直接訪問本方法局部變量
        System.out.println(this.name);//訪問本類成員變量
        System.out.println(super.num);//訪問父類成員變量
        this.method2();//訪問本類另一個成員方法
    }

8.最后,繼承三大特點:

1.單繼承:一個子類只有一個直接父類
2.多級繼承:父類、子類、子類也可作父類再向下延伸,最上級為java.lang.object類
3.一個父類可以有多個子類

二、多態(tài)

1.多態(tài)性:父類引用指向子類對象
多態(tài)的一個用處:無論右邊new的時候換成哪個子類對象,等號左邊調(diào)用方法都不會發(fā)生變化

格式:
父類名稱 對象名 = new 子類名稱();
或者:
接口名 對象名 = new 實現(xiàn)類名稱()。

2.成員方法:編譯看左,運行看右;
成員變量:編譯看左,運行也看左;實例變量不具備多態(tài)性.
代碼示范:

//前面省略部分Zi類已經(jīng)繼承Fu類
  public static void main(String[] args) {

        Fu one = new Zi();//多態(tài)的寫法
        one.methodcommon();//重名時,成員方法優(yōu)先使用子類(new誰先調(diào)用誰)。

        one.fu1();//它的編譯時類型為Fu,可以調(diào)用Fu中的方法
//      one.zi1(); 該調(diào)用編譯時會報錯,因為它的編譯時類型為Fu,無法調(diào)用zi1方法;
        System.out.println(one.num);//優(yōu)先看左邊Fu類

        Zi two = (Zi) one;//將父類對象還原成子類對象。
        System.out.println(one instanceof Fu);//輸出true,one可以做Fu類的實例對象
        System.out.println(one instanceof Zi);//輸出true,one可以做Zi類的實例對象
    }

3.轉(zhuǎn)型多態(tài)寫法左父右子是正常的向上轉(zhuǎn)型
4.向下轉(zhuǎn)型:為了讓對象調(diào)用子類方法(向上轉(zhuǎn)型只能調(diào)用左邊編譯類型的父類方法)
左子類右父類,是一個還原的過程,將父類對象還原成子類對象,且不能向下轉(zhuǎn)成別的子類。


格式:  子類名 對象名 = (子類名) 父類對象名;     (后者也可以是接口)

Fu fu = new Fu();//向上轉(zhuǎn)型創(chuàng)建父類對象
Zi two = (Zi) one;//將父類對象還原成子類對象。

5.強(qiáng)制向下轉(zhuǎn)型時,判斷前面的對象是否是后面類型的實例,是否可以成功轉(zhuǎn)換,從而保證代碼更加健壯。
格式: 對象 instanceof 類型
得到一個boolean值結(jié)果(true/false),判斷前面的對象能否作為后面類型的實例

Zi two = (Zi) one;//將父類對象還原成子類對象。
        System.out.println(one instanceof Fu);//輸出true,one可以做Fu類的實例對象
        System.out.println(one instanceof Zi);//輸出true,one可以做Zi類的實例對象

三、接口

1.接口定義了某一批類需要遵守的規(guī)范。這就意味著接口里通常是定義一組公用方法。
2.接口是一種引用數(shù)據(jù)類型(類、接口、數(shù)組),注意其中的抽象方法。
3.接口可以繼承接口,但不能繼承類。
4.Java9 里可以有常量、抽象方法、默認(rèn)方法、靜態(tài)方法、私有方法。
5.備注:接口編譯后生成的同樣是.class的字節(jié)碼文件

//格式
public interface 接口名稱(首字母大寫){
    //抽象方法
}

  • 接口里的成員變量只能是常量,必須用public static final修飾,可省略
 //final即為不可改變
    public static final int MAX_NUMBER = 20;

  • 接口里的[普通方法]只能是抽象方法,public abstract可以省略
 public abstract void out();
                 void getDate();

  • 接口中的[默認(rèn)方法]需要用default修飾
    /*
    當(dāng)接口新添加方法時,新方法寫為默認(rèn)方法,則可以不去動其實現(xiàn)類,默認(rèn)方法自動被其繼承
    默認(rèn)方法同樣可以被覆寫。
     */
    public default void print() {
        foo();
        System.out.println("默認(rèn)方法調(diào)用3");
    }

  • 接口中定義[靜態(tài)方法],需要用static修飾
public static void staticTest() {
        System.out.println("靜態(tài)方法!");
    }

  • 當(dāng)倆默認(rèn)方法中有重復(fù)內(nèi)容時,抽取出來定義私有方法
//定義私有默認(rèn)方法,給默認(rèn)方法調(diào)用,但不應(yīng)被實現(xiàn)類使用,所以權(quán)限為私有
    private void foo() {
        System.out.println("默認(rèn)方法調(diào)用2");
    }

//定義私有靜態(tài)方法,給靜態(tài)方法調(diào)用,但不應(yīng)被實現(xiàn)類使用,所以權(quán)限為私有
    private static void bar() {
        System.out.println("bar私有靜態(tài)方法");
    }
}

  • 接口不能創(chuàng)建實例,但能用于聲明引用類型變量,且必須引用到實現(xiàn)類的對象;
  • 一個實現(xiàn)類可以同時實現(xiàn)多個接口
//格式:
.public class 實現(xiàn)類名稱 impliments{
    //必須覆寫接口中所有抽象方法;
},  

  • 在實現(xiàn)類(impliments)中進(jìn)行接口的實現(xiàn):
//
public class Demo01InterfaceImpl implements Demo01Interface,Demo02Interface {
    //1,2接口都有out抽象方法,但只需覆寫一次
    @Override
    public void out() {
        System.out.println("抽象方法覆寫!");
    }

    @Override
    public void getDate() {
        System.out.println("抽象方法覆寫!");
    }

    @Override
    public void print(){
        System.out.println("沖突的默認(rèn)方法也需要覆寫!");//不沖突則不用覆寫
    }
}

  • 然后在main類里創(chuàng)建實現(xiàn)類的對象,進(jìn)行調(diào)用
public class Impliments  {

    public static void main(String[] args) {
        //創(chuàng)建實現(xiàn)類的對象
        Demo01InterfaceImpl ImplementationObject1 = new Demo01InterfaceImpl();
        ImplementationObject1.getDate();
        ImplementationObject1.out();
        ImplementationObject1.print();//調(diào)用實現(xiàn)類里繼承自接口的默認(rèn)方法。

        //接口里的靜態(tài)方法只能通過接口名稱直接調(diào)用。
        Demo01Interface.staticTest();

        //通過接口名直接訪問常量。
        System.out.println(Demo01Interface.MAX_NUMBER);
    }
}

  • 接口是多繼承,一個接口可以有多個父接口。
  • 多個父接口中的抽象方法如果存在重名,正常覆寫;但默認(rèn)方法重名需要帶有default關(guān)鍵字覆寫。
  • 正常不沖突抽象方法不需要再覆寫(實現(xiàn)類多個接口時也是如此)。
//接口的多繼承,同樣使用extends關(guān)鍵字
public interface Demo03InterfaceExtends extends Demo01Interface,Demo02Interface {
    @Override
    default void print() {
        //覆寫父接口的默認(rèn)方法不能省略default關(guān)鍵字
    }
}

四、抽象類

  • 抽象方法:加上abstract關(guān)鍵字,去掉大括號,直接分號結(jié)束;
  • 抽象類:抽象方法所在的類必須是抽象類,再class之前寫上abstract即可
  • 不能直接new抽象類對象,必須用一個子類來繼承抽象父類
    (抽象類對象調(diào)用的方法存在沒有具體內(nèi)容的方法體,因此沒有意義)
  • 創(chuàng)建子類對象,不可創(chuàng)建抽象父類對象;
public abstract class demo01Abstract {

    public abstract void method1();
    public abstract void method2();
}

  • 子類必須覆寫抽象類中的所有抽象方法(去掉abstrat,補上大括號)。
    (假設(shè)不全部覆寫,對象調(diào)用的方法存在抽象方法,沒有意義)
//使用extends繼承抽象父類
public abstract class demo02Zi extends demo01Abstract {

    //只覆寫了一個抽象方法,沒有將抽象方法全部覆寫完,也就是說本子類還存在著繼承下來的未覆寫的抽象方法
    //所以該類也同樣是抽象類

    @Override
    public void method1() {
        System.out.println("已經(jīng)覆寫第method1方法!");
    }
}

//在這個子子類中已經(jīng)將所有抽象方法全部覆寫,所以該類不再是抽象類!
public class demo03Sun extends demo02Zi {
    @Override
    public void method2() {
        System.out.println("已經(jīng)覆寫method2方法!");
    }
}

  • 最后在main類中的main方法里創(chuàng)建對象進(jìn)行調(diào)用即可。

五、final關(guān)鍵字

  • final表示它修飾的類、方法、成員變量、局部變量不可改變。
  • final修飾的類不可被繼承下去。無子類,不可被覆蓋重寫。
public final class 類名(){}

  • final修飾的方法不可被覆蓋重寫。
public final void method(){}

  • 類和方法不能同時使用final和abstract,二者矛盾。abstract表示抽象,是待定的;final表示最終的,是確定的。
  • final修飾局部變量,若是基本數(shù)據(jù)類型的數(shù)值,則不可改變;若是引用數(shù)據(jù)類型,則地址值不可改變,但地址指向的對象的內(nèi)容可以改變。
  • final修飾成員變量,也不可變,但必須要進(jìn)行手動賦值,成員變量加final后不允許再擁有默認(rèn)值。
public final class Demo01Final {

    public static void main(String[] args) {
        int NUM = 1;
        System.out.println(NUM);
        NUM = 2;//可以改變
        System.out.println(NUM);

        final int NUM1 = 2;
//      NUM1 = 3;  錯誤,NUM是確定的值,不可被改變。
    }
}

六、權(quán)限修飾符

  • 權(quán)限大小:
    四種權(quán)限修飾符,訪問權(quán)限從大到小:
    public > protected > 空 > private
    同一個類: yes yes yes yes
    同一個包: yes yes yes no
    不同包子類: yes yes no no
    不同包非子類:yes no no no
    在這里插入圖片描述

七、內(nèi)部類

一個外部類包含的一個嵌套的類,叫內(nèi)部類。
分類:
1.成員內(nèi)部類。
2.局部內(nèi)部類(包含匿名內(nèi)部類)。

  • 注意:內(nèi)部類可以無限制地訪問外部類,外部類訪問內(nèi)部類需要內(nèi)部類對象。
  • 各個類對應(yīng)可以使用的權(quán)限修飾符如下:
    外部類:public/(default)
    成員內(nèi)部類:public.protect.(default).private
    局部內(nèi)部類:什么都沒有,注意并不是(default)
  • 內(nèi)部類定義示例:
public class main {
    private String name = "成員變量";

    //定義一個成員內(nèi)部類
    public class innerClass {
        private String innername = "內(nèi)部成員變量";
    }

        // 定義一個成員內(nèi)部類內(nèi)的成員方法
        public void innermethod1() {
            System.out.println("內(nèi)部類方法");
            System.out.println(name);
        }

  }

使用內(nèi)部類的兩種方式:
1.直接:在main方法中創(chuàng)建內(nèi)部類對象:格式:
外.內(nèi) = new 外().內(nèi)();

外部類名稱.內(nèi)部類名稱 對象名 = new 外部類名稱().new 內(nèi)部類名稱();

 public static void main(String[] args) {
        //直接創(chuàng)建內(nèi)部類的對象。
        InnerclassUsing.innerClass object = new InnerclassUsing().new innerClass();
        object.innermethod1();
    }

2.間接:在外部類的方法中,只用內(nèi)部類,main只是調(diào)用外部類的方法,通過外部類方法訪問內(nèi)部類。

public class InnerclassUsing {

    private String name = "成員變量";

    //定義一個成員內(nèi)部類
    public class innerClass {

        private String innername = "內(nèi)部成員變量";

        // 定義一個成員內(nèi)部類的成員方法
        public void innermethod1() {
            System.out.println("內(nèi)部類方法");
            System.out.println(name);
        }
    }

    public void outMethod() {
        System.out.println("外部類成員方法");

  //    System.out.println(innername);  錯誤。

        //通過匿名對象訪問內(nèi)部類變量和方法
        System.out.println(new innerClass().innername);

        //創(chuàng)建匿名對象并調(diào)用innermethod1方法。
        new innerClass().innermethod1();
    }

 }

內(nèi)部類的重名變量訪問格式:

  • 本方法: 空
  • 本類成員變量:this.
  • 外部類成員變量:外部類的名稱.this.
public class Demo03CommonName {
    //外部類成員變量
    int NAME = 1;

    public class innerClass{
        //內(nèi)部類成員變量
        int NAME = 2;

        public void method (){
            //內(nèi)部類局部變量
            int NAME = 3;

            System.out.println(NAME);//3,局部變量,就近原則。
            System.out.println(this.NAME);//2,本類成員變量。
            System.out.println(Demo03CommonName.this.NAME);//1,外部類的成員變量;
        }
    }
}

如果一個類定義在方法內(nèi)部,那么這個類叫局部內(nèi)部類。
局部內(nèi)部類只能被當(dāng)前所屬的方法所使用,外部不可。

格式:

public class Localinnerclass {
    String NAME = "外部成員變量";

    public void method(){

        //定義局部內(nèi)部類
        class localLinnerClass{
            String ONE = "局部內(nèi)部類成員變量";

            public void nmethod2(){
                System.out.println("局部內(nèi)部類的成員方法");
                System.out.println(ONE);
            }
        }

    }
}

局部內(nèi)部類,如果希望訪問所在方法的局部變量,該變量應(yīng)該滿足【有效final】的條件

public class Demo04Final {

    public void method1(){

        //這里即使不寫final的話,不去修改 也算是有效final [從java8開始]
        final String NAME = "bilibili";

        class LocalInnerclass{

            public void localInnerMethod(){
                //局部內(nèi)部類內(nèi)的方法訪問所在類外部的方法的局部變量
                System.out.println(NAME);
            }
        }

    }
}

當(dāng)接口是實現(xiàn)類只使用唯一一次時,可以使用匿名內(nèi)部類

  • 格式
接口名稱 對象名 = new 接口名稱(){
    //這里進(jìn)行抽象方法的覆寫。
};    //別忘了結(jié)尾的分號

匿名內(nèi)部類在創(chuàng)建對象的時候,只能使用唯一一次
匿名對象在使用方法時,只能使用唯一一次
匿名內(nèi)部類是省略了(實現(xiàn)類/子類名稱),而匿名對象則是省略了對象名稱,二者不同。

//當(dāng)實現(xiàn)類只使用一次時,可以使用匿名內(nèi)部類的寫法!
        Anonymous obj6 = new Anonymous() {
            //覆寫匿名內(nèi)部類里所有抽象方法!
            @Override
            public void method1() {
                System.out.println("bilibili?");
            }
            @Override
            public void method2(){
                System.out.println("覆寫method!");
            }
        };
        obj6.method1();//打印內(nèi)容
        obj6.method2();

將類作為成員變量的寫法

//定義一個武器類
public class Weapon {
    private String itsname;//武器名稱
    private int attacknum;//武器攻擊力

    //無參構(gòu)造方法
    public Weapon() {
    }
    //全參方法
    public Weapon(String itsname, int attacknum) {
        this.itsname = itsname;
        this.attacknum = attacknum;
    }
    //get名字
    public String getItsname() {
        return itsname;
    }
    //set名字
    public void setItsname(String itsname) {
        this.itsname = itsname;
    }
    //get攻擊力
    public int getAttacknum() {
        return attacknum;
    }
    //set攻擊力
    public void setAttacknum(int attacknum) {
        this.attacknum = attacknum;
    }
}

//定義一個女武神類
public class Valkyrie1 {
    private String name;//女武神之名
    private Weapon weapon;//將武器類變?yōu)槌蓡T變量 交給女武神類

    //女武神攻擊方法
    public void attack(){
        System.out.println(name + "使用的" + weapon.getItsname() + "具有" + weapon.getAttacknum() +"點攻擊力");
    }

    //無參構(gòu)造
    public Valkyrie1() {};
    //全參
    public Valkyrie1(String name, Weapon weapon) {
        this.name = name;
        this.weapon = weapon;
    }
    //get女武神名字
    public String getName() {
        return name;
    }
    //set女武神名字
    public void setName(String name) {
        this.name = name;
    }
    //get女武神武器
    public Weapon getWeapon() {
        return weapon;
    }
    //set女武神武器
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
}

  • 定義了女武神類和武器類后,在main方法中進(jìn)行調(diào)用
        Valkyrie1 valkyrie = new Valkyrie1();//創(chuàng)建一個女武神
        valkyrie.setName("bronya"); //set女武神名字叫bronya

        Weapon weapon = new Weapon("真理之鑰",1000);//創(chuàng)建一把武器,并同時賦予名稱和攻擊力
//     也可以分開寫: weapon.setItsname("真理之鑰");//武器名字
//     也可以分開寫: weapon.setAttacknum(1000);//武器攻擊力

        valkyrie.setWeapon(weapon);//將定義好的武器交給女武神

        valkyrie.attack();//最后,女武神使用這把武器進(jìn)行攻擊

**

  • 關(guān)注我,一起學(xué)習(xí)、一起進(jìn)步,無限期更新,期待下一期哦!
  • 關(guān)注微信公眾號 崩天的勾玉 回復(fù) java 免費領(lǐng)取視頻學(xué)習(xí)資料
  • Bye!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內(nèi)容