主頁 >  其他 > Java基礎知識

Java基礎知識

2020-09-14 16:02:14 其他

前述:利用一段較為充足暑假時間,對以前的Java學習進行一個系統性的回顧,對于部分知識點進行記錄和積累,本部分主要記錄了Java中各種概念和細節基礎,作為筆記,便于理解、學習和記憶,

Java基礎筆記

一 區域變數和成員變數:

  • 定義位置不一樣【重點】
    • 區域變數:方法的內部
    • 成員變數:在方法的外部,直接寫在類當中
  • 作用范圍不一樣【重點】
    • 區域變數:只有方法當中才可以使用,出了方法就不能再用
    • 成員變數:整個類全都可以通用,
  • 默認值不一樣【重點】
    • 區域變數:沒有默認值,如果要想使用,必須手動進行賦值
    • 成員變數:如果沒有賦值,會有默認值,規則和陣列一樣
  • 記憶體的位置不一樣(了解)
    • 區域變數:位于堆疊記憶體
    • 成員變數:位于堆記憶體
  • 生命周期不一樣(了解)
    • 區域變數:隨著方法進堆疊而誕生,隨著方法出堆疊而消失
    • 成員變數:隨著物件創建而誕生,隨著物件被垃圾回收而消失
  • 注意:
    • 當方法的區域變數和類的成員變數重名的時候,根據"就近原則",優先使用區域變數,
    • 如果需要訪問本類當中的成員變數,需要使用格式:this.成員變數名,通過誰呼叫的方法,誰就是this,
 1 public class Demo01VariableDifference {
 2 
 3     String name; // 成員變數
 4 
 5     public void methodA() {
 6         int num = 20; // 區域變數
 7         System.out.println(num);
 8         System.out.println(name);
 9     }
10 
11     public void methodB(int param) { // 方法的引數就是區域變數
12         // 引數在方法呼叫的時候,必然會被賦值的,
13         System.out.println(param);
14 
15         int age; // 區域變數
16 //        System.out.println(age); // 沒賦值不能用
17 
18 //        System.out.println(num); // 錯誤寫法!
19         System.out.println(name);
20     }
21 
22 }

 

 

二 面向物件的三大特征:

封裝、繼承和多型

  • 封裝:封裝性就是將一些細節資訊隱藏起來,對外界不可見
    • 方法就是一種封裝
    • 關鍵字private也是一種封裝
      • 一旦使用了private進行修飾,那么本類當中仍然可以隨意訪問,但是超出了本類范圍之外就不能再直接訪問了,
      • 間接訪問private成員變數,就是定義一對兒Getter/Setter方法

 

 

三 構造方法:

構造方法是專門用來創建物件的方法,當我們通過關鍵字new來創建物件時,其實就是在呼叫構造方法,

  • 注意事項:
    • 構造方法的名稱必須和所在的類名稱完全一樣,就連大小寫也要一樣
    • 構造方法不要寫回傳值型別,連void都不寫
    • 構造方法不能return一個具體的回傳值
    • 如果沒有撰寫任何構造方法,那么編譯器將會默認贈送一個構造方法,沒有引數、方法體什么事情都不做,
    • 一旦撰寫了至少一個構造方法,那么編譯器將不再贈送,
    • 構造方法也是可以進行多載(方法名稱相同,引數串列不同)的,
 1 public class Student {
 2 
 3     // 成員變數
 4     private String name;
 5     private int age;
 6 
 7     // 無引數的構造方法
 8     public Student() {
 9     }
10 
11     // 全引數的構造方法
12     public Student(String name, int age) {
13         this.name = name;
14         this.age = age;
15     }
16 }

 

 

四 JavaBean:

一個標準的類又稱為JavaBean,通常由四部分組成

  • 所有的成員變數都要使用private關鍵字修飾
  • 為每一個成員變數撰寫一對兒Getter/Setter方法
  • 撰寫一個無引數的構造方法
  • 撰寫一個全引數的構造方法

 

 

五 匿名物件:

匿名物件就是只有右邊的物件,沒有左邊的名字和賦值運算子

  • 注意事項:匿名物件只能使用唯一的一次,下次再用不得不再創建一個新物件,
  • 使用建議:如果確定有一個物件只需要使用唯一的一次,就可以用匿名物件,
 1         // 匿名物件
 2         new Person().name = "張磊";
 3 
 4         // 普通使用方式
 5         Scanner sc = new Scanner(System.in);
 6         int num = sc.nextInt();
 7 
 8         // 匿名物件的方式
 9         int num = new Scanner(System.in).nextInt();
10         System.out.println("輸入的是:" + num);
11 
12         // 使用一般寫法傳入引數
13         Scanner sc = new Scanner(System.in);
14         methodParam(sc);
15 
16         // 使用匿名物件來進行傳參
17         methodParam(new Scanner(System.in));

 

 

六 ArrayList類:

ArrayList中常用的方法

  • public boolean add(E e):向集合當中添加元素,引數的型別和泛型一致,回傳值代表添加是否成功,
    • 備注:對于ArrayList集合來說,add添加動作一定是成功的,所以回傳值可用可不用,但是對于其他集合(今后學習)來說,add添加動作不一定成功,
  • public E get(int index):從集合當中獲取元素,引數是索引編號,回傳值就是對應位置的元素,
  • public E remove(int index):從集合當中洗掉元素,引數是索引編號,回傳值就是被洗掉掉的元素,
  • public int size():獲取集合的尺寸長度,回傳值是集合中包含的元素個數,

 

向集合ArrayList當中存盤基本型別資料,必須使用基本型別對應的“包裝類”

基本型別 包裝類(參考型別,包裝類都位于java.lang包下)
byte Byte
short Short
int Integer      【特殊】
long Long
float Float
double Double
char Character   【特殊】
boolean Boolean

 

注意事項:

  • ArrayList集合的長度可以隨意變化,與陣列不同
  • 對于ArrayList來說,有一個尖括號<E>代表泛型,
    • 泛型:也就是裝在集合當中的所有元素,全都是統一的什么型別,
    • 注意:泛型只能是參考型別,不能是基本型別,
  • 對于ArrayList集合來說,直接列印得到的不是地址值,而是內容,如果內容是空,得到的是空的中括號:[]

 

 

七 String類:

字串的特點:

  • 字串的內容永不可變,【重點】
  • 正是因為字串不可改變,所以字串是可以共享使用的,
  •  字串效果上相當于是char[]字符陣列,但是底層原理是byte[]位元組陣列,

 

創建字串的常見3+1種方式

  • 三種構造方法:
    • public String():創建一個空白字串,不含有任何內容,
    • public String(char[] array):根據字符陣列的內容,來創建對應的字串,
    • public String(byte[] array):根據位元組陣列的內容,來創建對應的字串,
  • 一種直接創建:
    • String str = "Hello"; // 右邊直接用雙引號
 1 public class Demo01String {
 2 
 3     public static void main(String[] args) {
 4         // 使用空參構造
 5         String str1 = new String(); // 小括號留空,說明字串什么內容都沒有,
 6         System.out.println("第1個字串:" + str1);
 7 
 8         // 根據字符陣列創建字串
 9         char[] charArray = { 'A', 'B', 'C' };
10         String str2 = new String(charArray);
11         System.out.println("第2個字串:" + str2);
12 
13         // 根據位元組陣列創建字串
14         byte[] byteArray = { 97, 98, 99 };
15         String str3 = new String(byteArray);
16         System.out.println("第3個字串:" + str3);
17 
18         // 直接創建
19         String str4 = "Hello";
20         System.out.println("第4個字串:" + str4);
21     }
22 
23 }

 

String當中與轉換相關的常用方法

  • public char[] toCharArray():將當前字串拆分成為字符陣列作為回傳值,
  • public byte[] getBytes():獲得當前字串底層的位元組陣列,
  • public String replace(CharSequence oldString, CharSequence newString):將所有出現的老字串替換成為新的字串,回傳替換之后的結果新字串,
 1 public class Demo04StringConvert {
 2 
 3     public static void main(String[] args) {
 4         // 轉換成為字符陣列
 5         char[] chars = "Hello".toCharArray();
 6         System.out.println(chars[0]); // H
 7         System.out.println(chars.length); // 5
 8         System.out.println("==============");
 9 
10         // 轉換成為位元組陣列
11         byte[] bytes = "abc".getBytes();
12         for (int i = 0; i < bytes.length; i++) {
13             System.out.println(bytes[i]);
14         }
15         System.out.println("==============");
16 
17         // 字串的內容替換
18         String str1 = "How do you do?";
19         String str2 = str1.replace("o", "*");
20         System.out.println(str1); // How do you do?
21         System.out.println(str2); // H*w d* y*u d*?
22         System.out.println("==============");
23 
24     }
25 
26 }

 

 

八 Static關鍵字:

Static修飾成員變數與方法

  • 如果一個成員變數使用了static關鍵字,那么這個變數不再屬于物件自己,而是屬于所在的類,多個物件共享同一份資料
  • 一旦使用static修飾成員方法,那么這就成為了靜態方法,靜態方法不屬于物件,而是屬于類的,
    • 如果沒有static關鍵字,那么必須首先創建物件,然后通過物件才能使用它,
    • 如果有了static關鍵字,那么不需要創建物件,直接就能通過類名稱來使用它,
  • 無論是成員變數,還是成員方法,如果有了static,都推薦使用類名稱進行呼叫,
    • 靜態變數:類名稱.靜態變數
    • 靜態方法:類名稱.靜態方法()
  • 注意事項:
    • 靜態不能直接訪問非靜態,
        因為在記憶體當中是【先】有的靜態內容,【后】有的非靜態內容,
        “先人不知道后人,但是后人知道先人,”
    • 靜態方法當中不能用this,
        this代表當前物件,通過誰呼叫的方法,誰就是當前物件,

 

靜態代碼塊

  • 格式:
1 public class 類名稱 {
2     static {
3         // 靜態代碼塊的內容
4     }
5 }
  • 特點:
    • 當第一次用到本類時,靜態代碼塊執行唯一的一次,
    • 靜態內容總是優先于非靜態,所以靜態代碼塊比構造方法先執行, 
  • 靜態代碼塊的典型用途:用來一次性地對靜態成員變數進行賦值,

 

 

九 Arrays類:

java.util.Arrays是一個與陣列相關的工具類,里面提供了大量靜態方法,用來實作陣列常見的操作

  • public static String toString(陣列):將引數陣列變成字串(按照默認格式:[元素1, 元素2, 元素3...])
  • public static void sort(陣列):按照默認升序(從小到大)對陣列的元素進行排序,
  • 備注:
    • 如果是數值,sort默認按照升序從小到大
    • 如果是字串,sort默認按照字母升序
    • 如果是自定義的型別,那么這個自定義的類需要有Comparable或者Comparator介面的支持,

 

 

十 繼承:

繼承的基本概念圖

 

 在繼承的關系中,“子類就是一個父類”,也就是說,子類可以被當做父類看待

1 定義父類的格式:(一個普通的類定義)
2 public class 父類名稱 {
3     // ...
4 }
5 
6 定義子類的格式:
7 public class 子類名稱 extends 父類名稱 {
8     // ...
9 }

 

 在父子類的繼承關系當中,如果成員變數重名,則創建子類物件時,訪問有兩種方式

  • 直接通過子類物件訪問成員變數:等號左邊是誰,就優先用誰,沒有則向上找,
  • 間接通過成員方法訪問成員變數:該方法屬于誰,就優先用誰,沒有則向上找,
 1 public class Demo01ExtendsField {
 2 
 3     public static void main(String[] args) {
 4         Fu fu = new Fu(); // 創建父類物件
 5         System.out.println(fu.numFu); // 只能使用父類的東西,沒有任何子類內容
 6         System.out.println("===========");
 7 
 8         Zi zi = new Zi();
 9 
10         System.out.println(zi.numFu); // 10
11         System.out.println(zi.numZi); // 20
12         System.out.println("===========");
13 
14         // 等號左邊是誰,就優先用誰
15         System.out.println(zi.num); // 優先子類,200
16 //        System.out.println(zi.abc); // 到處都沒有,編譯報錯!
17         System.out.println("===========");
18 
19         // 這個方法是子類的,優先用子類的,沒有再向上找
20         zi.methodZi(); // 200
21         // 這個方法是在父類當中定義的,
22         zi.methodFu(); // 100
23     }
24 
25 }
 1 public class Fu {
 2 
 3     int numFu = 10;
 4 
 5     int num = 100;
 6 
 7     public void methodFu() {
 8         // 使用的是本類當中的,不會向下找子類的
 9         System.out.println(num);
10     }
11 
12 }
 1 public class Zi extends Fu {
 2 
 3     int numZi = 20;
 4 
 5     int num = 200;
 6 
 7     public void methodZi() {
 8         // 因為本類當中有num,所以這里用的是本類的num
 9         System.out.println(num);
10     }
11 }

 

 各類變數的訪問方式

  • 區域變數: 直接寫成員變數名
  • 本類的成員變數: this.成員變數名
  • 父類的成員變數: super.成員變數名

 

 在父子類的繼承關系當中,創建子類物件,訪問成員方法的規則

  • 創建的物件是誰,就優先用誰,如果沒有則向上找,
  • 無論是成員方法還是成員變數,如果沒有都是向上找父類,絕對不會向下找子類的

 

方法覆寫重寫

  •  必須保證父子類之間方法的名稱相同,引數串列也相同,
    • @Override:寫在方法前面,用來檢測是不是有效的正確覆寫重寫,這個注解就算不寫,只要滿足要求,也是正確的方法覆寫重寫,
  • 子類方法的回傳值必須【小于等于】父類方法的回傳值范圍,
    • 小擴展提示:java.lang.Object類是所有類的公共最高父類(祖宗類),java.lang.String就是Object的子類,
  • 子類方法的權限必須【大于等于】父類方法的權限修飾符,
    • 小擴展提示:public > protected > (default) > private
    • 備注:(default)不是關鍵字default,而是什么都不寫,留空,、
  • 方法的覆寫重寫特點:創建的是子類物件,則優先用子類方法
  • 與多載的區別:
    • 重寫(Override) :方法的名稱一樣,引數串列【也一樣】,覆寫、覆寫,
    • 多載(Overload):方法的名稱一樣,引數串列【不一樣】,

 

方法覆寫重寫的應用場景


 繼承關系中,父子類構造方法的訪問特點

  • 子類構造方法當中有一個默認隱含的“super()”呼叫,所以一定是先呼叫的父類構造,后執行的子類構造,
  • 子類構造可以通過super關鍵字來呼叫父類多載構造,
  • super的父類構造呼叫,必須是子類構造方法的第一個陳述句,不能一個子類構造呼叫多次super構造,
  • 總結:子類必須呼叫父類構造方法,不寫則贈送super();寫了則用寫的指定的super呼叫,super只能有一個,還必須是第一個,
 1 public class Zi extends Fu {
 2 
 3     public Zi() {
 4         super(); // 在呼叫父類無參構造方法
 5 //        super(20); // 在呼叫父類多載的構造方法
 6         System.out.println("子類構造方法!");
 7     }
 8 
 9     public void method() {
10 //        super(); // 錯誤寫法!只有子類構造方法,才能呼叫父類構造方法,
11     }
12 
13 }

 

Java繼承的三個特點

 

 

十一 super&this:

super關鍵字的用法有三種(用于訪問父類的相關內容)

  1、在子類的成員方法中,訪問父類的成員變數,   2、在子類的成員方法中,訪問父類的成員方法,   3、在子類的構造方法中,訪問父類的構造方法,
 1 public class Zi extends Fu {
 2 
 3     int num = 20;
 4 
 5     public Zi() {
 6         super();
 7     }
 8 
 9     public void methodZi() {
10         System.out.println(super.num); // 父類中的num
11     }
12 
13     public void method() {
14         super.method(); // 訪問父類中的method
15         System.out.println("子類方法");
16     }
17 
18 }
1 public class Fu {
2 
3     int num = 10;
4 
5     public void method() {
6         System.out.println("父類方法");
7     }
8 
9 }

 

 this關鍵字的用法有三種(用來訪問本類內容)

  1、在本類的成員方法中,訪問本類的成員變數,   2、在本類的成員方法中,訪問本類的另一個成員方法,   3、在本類的構造方法中,訪問本類的另一個構造方法,   在第三種用法當中要注意:     this(...)呼叫也必須是構造方法的第一個陳述句,唯一一個,     super和this兩種構造呼叫,不能同時使用,
 1 public class Zi extends Fu {
 2 
 3     int num = 20;
 4 
 5     public Zi() {
 6 //        super(); // 這一行不再贈送
 7         this(123); // 本類的無參構造,呼叫本類的有參構造
 8 //        this(1, 2); // 錯誤寫法!
 9     }
10 
11     public Zi(int n) {
12         this(1, 2);
13     }
14 
15     public Zi(int n, int m) {
16     }
17 
18     public void showNum() {
19         int num = 10;
20         System.out.println(num); // 區域變數
21         System.out.println(this.num); // 本類中的成員變數
22         System.out.println(super.num); // 父類中的成員變數
23     }
24 
25     public void methodA() {
26         System.out.println("AAA");
27     }
28 
29     public void methodB() {
30         this.methodA();
31         System.out.println("BBB");
32     }
33 
34 }
1 public class Fu {
2 
3     int num = 30;
4 
5 }

 

 

十二 抽象類:

相關概念

  • 抽象方法:就是加上abstract關鍵字,然后去掉大括號,直接分號結束,
  • 抽象類:抽象方法所在的類,必須是抽象類才行,在class之前寫上abstract即可,

 

抽象類與抽象方法的關系

  • 一個抽象類不一定含有抽象方法
  • 要保證抽象方法所在的類是抽象類
  • 沒有抽象方法的抽象類,也不能直接創建物件,在一些特殊場景下有用途
1 public abstract class MyAbstract {
2 }

 

如何使用抽象類和抽象方法

  • 不能直接創建new抽象類物件,
  • 必須用一個子類來繼承抽象父類,
  • 子類必須覆寫重寫抽象父類當中所有的抽象方法,
  • 覆寫重寫(實作):子類去掉抽象方法的abstract關鍵字,然后補上方法體大括號,
  • 創建子類物件進行使用
 1 public abstract class Animal {
 2 
 3     // 這是一個抽象方法,代表吃東西,但是具體吃什么(大括號的內容)不確定,
 4     public abstract void eat();
 5 
 6     // 這是普通的成員方法
 7 //    public void normalMethod() {
 8 //
 9 //    }
10 
11 }
1 public class Cat extends Animal {
2 
3     @Override
4     public void eat() {
5         System.out.println("貓吃魚");
6     }
7 
8 }
public class DemoMain {

    public static void main(String[] args) {
//        Animal animal = new Animal(); // 錯誤寫法!不能直接創建抽象類物件

        Cat cat = new Cat();
        cat.eat();
    }

}

 

 

十三 介面:

介面就是多個類的公共規范,介面是一種參考資料型別,最重要的內容就是其中的:抽象方法

  • 備注:換成了關鍵字interface之后,編譯生成的位元組碼檔案仍然是:.java --> .class
  • 介面的格式:
1 public interface 介面名稱 {
2     // 介面內容
3 }

 

 介面使用步驟:

  1、介面不能直接使用,必須有一個“實作類”來“實作”該介面,
1 public class 實作類名稱 implements 介面名稱 {
2     // ...
3 }
  2、介面的實作類必須覆寫重寫(實作)介面中所有的抽象方法,實作:去掉abstract關鍵字,加上方法體大括號,   3、創建實作類的物件,進行使用,   注意事項:如果實作類并沒有覆寫重寫介面中所有的抽象方法,那么這個實作類自己就必須是抽象類,
 1 public class Demo01Interface {
 2 
 3     public static void main(String[] args) {
 4         // 錯誤寫法!不能直接new介面物件使用,
 5 //        MyInterfaceAbstract inter = new MyInterfaceAbstract();
 6 
 7         // 創建實作類的物件使用
 8         MyInterfaceAbstractImpl impl = new MyInterfaceAbstractImpl();
 9         impl.methodAbs1();
10         impl.methodAbs2();
11     }
12 
13 }

 

 在任何版本的Java中,介面都能定義抽象方法

  •  格式:
public abstract 回傳值型別 方法名稱(引數串列);
  • 注意事項:
    • 介面當中的抽象方法,修飾符必須是兩個固定的關鍵字:public abstract
    • 這兩個關鍵字修飾符,可以選擇性地省略,(今天剛學,所以不推薦,)
    • 方法的三要素,可以隨意定義,
 1 public interface MyInterfaceAbstract {
 2 
 3     // 這是一個抽象方法
 4     public abstract void methodAbs1();
 5 
 6     // 這也是抽象方法
 7     abstract void methodAbs2();
 8 
 9     // 這也是抽象方法
10     public void methodAbs3();
11 
12     // 這也是抽象方法
13     void methodAbs4();
14 
15 }
 1 public class MyInterfaceAbstractImpl implements MyInterfaceAbstract {
 2     @Override
 3     public void methodAbs1() {
 4         System.out.println("這是第一個方法!");
 5     }
 6 
 7     @Override
 8     public void methodAbs2() {
 9         System.out.println("這是第二個方法!");
10     }
11 
12     @Override
13     public void methodAbs3() {
14         System.out.println("這是第三個方法!");
15     }
16 
17     @Override
18     public void methodAbs4() {
19         System.out.println("這是第四個方法!");
20     }
21 }

 

 介面當中也可以定義“成員變數”,但是必須使用public static final三個關鍵字進行修飾(從效果上看,這其實就是介面的【常量】)

  • 格式:public static final 資料型別 常量名稱 = 資料值;
  • 備注:一旦使用final關鍵字進行修飾,說明不可改變,
  • 注意事項:
    • 介面當中的常量,可以省略public static final,注意:不寫也照樣是這樣,
    • 介面當中的常量,必須進行賦值;不能不賦值,
    • 介面中常量的名稱,使用完全大寫的字母,用下劃線進行分隔,(推薦命名規則)
1 public interface MyInterfaceConst {
2 
3     // 這其實就是一個常量,一旦賦值,不可以修改
4     public static final int NUM_OF_MY_CLASS = 12;
5 
6 }
1 public class Demo05Interface {
2 
3     public static void main(String[] args) {
4         // 訪問介面當中的常量
5         System.out.println(MyInterfaceConst.NUM_OF_MY_CLASS);
6     }
7 
8 }

 

 從Java 8開始,介面里允許定義默認方法

  • 格式:
1 public default 回傳值型別 方法名稱(引數串列) {
2     方法體
3 }
  • 備注:介面當中的默認方法,可以解決介面升級的問題
  • 使用方法:
    • 介面的默認方法,可以通過介面實作類物件,直接呼叫,
    • 介面的默認方法,也可以被介面實作類進行覆寫重寫,
 1 public class Demo02Interface {
 2 
 3     public static void main(String[] args) {
 4         // 創建了實作類物件
 5         MyInterfaceDefaultA a = new MyInterfaceDefaultA();
 6         a.methodAbs(); // 呼叫抽象方法,實際運行的是右側實作類,
 7 
 8         // 呼叫默認方法,如果實作類當中沒有,會向上找介面
 9         a.methodDefault(); // 這是新添加的默認方法
10         System.out.println("==========");
11 
12         MyInterfaceDefaultB b = new MyInterfaceDefaultB();
13         b.methodAbs();
14         b.methodDefault(); // 實作類B覆寫重寫了介面的默認方法
15     }
16 
17 }
 1 public interface MyInterfaceDefault {
 2 
 3     // 抽象方法
 4     public abstract void methodAbs();
 5 
 6     // 新添加了一個抽象方法
 7 //    public abstract void methodAbs2();
 8 
 9     // 新添加的方法,改成默認方法
10     public default void methodDefault() {
11         System.out.println("這是新添加的默認方法");
12     }
13 
14 }
1 public class MyInterfaceDefaultA implements MyInterfaceDefault {
2     @Override
3     public void methodAbs() {
4         System.out.println("實作了抽象方法,AAA");
5     }
6 }
 1 public class MyInterfaceDefaultB implements MyInterfaceDefault {
 2     @Override
 3     public void methodAbs() {
 4         System.out.println("實作了抽象方法,BBB");
 5     }
 6 
 7     @Override
 8     public void methodDefault() {
 9         System.out.println("實作類B覆寫重寫了介面的默認方法");
10     }
11 }

 

 從Java 8開始,介面當中允許定義靜態方法

  •  格式:
1 public static 回傳值型別 方法名稱(引數串列) {
2     方法體
3 } 
4 // 提示:就是將abstract或者default換成static即可,帶上方法體,
  • 注意事項:
    • 不能通過介面實作類的物件來呼叫介面當中的靜態方法,
    • 正確用法:通過介面名稱,直接呼叫其中的靜態方法,
      • 格式:介面名稱.靜態方法名(引數);
  • 代碼示例:
 1 public class Demo03Interface {
 2 
 3     public static void main(String[] args) {
 4         // 創建了實作類物件
 5         MyInterfaceStaticImpl impl = new MyInterfaceStaticImpl();
 6 
 7         // 錯誤寫法!
 8 //        impl.methodStatic();
 9 
10         // 直接通過介面名稱呼叫靜態方法
11         MyInterfaceStatic.methodStatic();
12     }
13 
14 }
1 public interface MyInterfaceStatic {
2 
3     public static void methodStatic() {
4         System.out.println("這是介面的靜態方法!");
5     }
6 
7 }
1 public class MyInterfaceStaticImpl implements MyInterfaceStatic {
2 }

 

從Java 9開始,介面當中允許定義私有方法

  • 問題描述:我們需要抽取一個共有方法,用來解決兩個默認方法之間重復代碼的問題,但是這個共有方法不應該讓實作類使用,應該是私有化的,
  • 解決方案:從Java 9開始,介面當中允許定義私有方法,
    • 普通私有方法:解決多個默認方法之間重復代碼問題,只有默認方法可以呼叫,
1 private 回傳值型別 方法名稱(引數串列) {
2     方法體
3 }
    • 靜態私有方法:解決多個靜態方法之間重復代碼問題,默認方法和靜態方法可以呼叫,
1 private static 回傳值型別 方法名稱(引數串列) {
2     方法體
3 }
  • 代碼示例:
 1 public class Demo04Interface {
 2 
 3     public static void main(String[] args) {
 4         MyInterfacePrivateB.methodStatic1();
 5         MyInterfacePrivateB.methodStatic2();
 6         // 錯誤寫法!
 7 //        MyInterfacePrivateB.methodStaticCommon();
 8     }
 9 
10 }
 1 public interface MyInterfacePrivateA {
 2 
 3     public default void methodDefault1() {
 4         System.out.println("默認方法1");
 5         methodCommon();
 6     }
 7 
 8     public default void methodDefault2() {
 9         System.out.println("默認方法2");
10         methodCommon();
11     }
12 
13     private void methodCommon() {
14         System.out.println("AAA");
15         System.out.println("BBB");
16         System.out.println("CCC");
17     }
18 
19 }
public class MyInterfacePrivateAImpl implements MyInterfacePrivateA {

    public void methodAnother() {
        // 直接訪問到了介面中的默認方法,這樣是錯誤的!
//        methodCommon();
    }

}
 1 public interface MyInterfacePrivateB {
 2 
 3     public static void methodStatic1() {
 4         System.out.println("靜態方法1");
 5         methodStaticCommon();
 6     }
 7 
 8     public static void methodStatic2() {
 9         System.out.println("靜態方法2");
10         methodStaticCommon();
11     }
12 
13     private static void methodStaticCommon() {
14         System.out.println("AAA");
15         System.out.println("BBB");
16         System.out.println("CCC");
17     }
18 
19 }

 

總結:在Java 9+版本中,介面的內容可以有

  1、成員變數其實是常量     格式:
      [public] [static] [final] 資料型別 常量名稱 = 資料值;
    注意:
      常量必須進行賦值,而且一旦賦值不能改變,       常量名稱完全大寫,用下劃線進行分隔,   2、介面中最重要的就是抽象方法     格式:
      [public] [abstract] 回傳值型別 方法名稱(引數串列);
    注意:       實作類必須覆寫重寫介面所有的抽象方法,除非實作類是抽象類,   3、從Java 8開始,介面里允許定義默認方法     格式:
      [public] default 回傳值型別 方法名稱(引數串列) { 方法體 }
    注意:       默認方法也可以被覆寫重寫   4、從Java 8開始,介面里允許定義靜態方法     格式:
      [public] static 回傳值型別 方法名稱(引數串列) { 方法體 }
    注意:       應該通過介面名稱進行呼叫,不能通過實作類物件呼叫介面靜態方法   5、從Java 9開始,介面里允許定義私有很乏     格式:
      普通私有方法:private 回傳值型別 方法名稱(引數串列) { 方法體 }
      靜態私有方法:private static 回傳值型別 方法名稱(引數串列) { 方法體 }
    注意:       private的方法只有介面自己才能呼叫,不能被實作類或別人使用,  

 使用介面的時候,需要注意

  1、介面是沒有靜態代碼塊或者構造方法的,   2、一個類的直接父類是唯一的,但是一個類可以同時實作多個介面,
1 public class MyInterfaceImpl implements MyInterfaceA, MyInterfaceB {
2     // 覆寫重寫所有抽象方法
3 }
  3、如果實作類所實作的多個介面當中,存在重復的抽象方法,那么只需要覆寫重寫一次即可,   4、如果實作類沒有覆寫重寫所有介面當中的所有抽象方法,那么實作類就必須是一個抽象類,   5、如果實作類鎖實作的多個介面當中,存在重復的默認方法,那么實作類一定要對沖突的默認方法進行覆寫重寫,   6、一個類如果直接父類當中的方法,和介面當中的默認方法產生了沖突,優先用父類當中的方法,
1 public class Demo01Interface {
2 
3     public static void main(String[] args) {
4         Zi zi = new Zi();
5         zi.method();
6     }
7 
8 }
public class Fu {

    public void method() {
        System.out.println("父類方法");
    }

}
1 public interface MyInterface {
2 
3     public default void method() {
4         System.out.println("介面的默認方法");
5     }
6 
7 }
1 public class Zi extends Fu implements MyInterface {
2 }
 1 public interface MyInterfaceA {
 2 
 3     // 錯誤寫法!介面不能有靜態代碼塊
 4 //    static {
 5 //
 6 //    }
 7 
 8     // 錯誤寫法!介面不能有構造方法
 9 //    public MyInterfaceA() {
10 //
11 //    }
12 
13     public abstract void methodA();
14 
15     public abstract void methodAbs();
16 
17     public default void methodDefault() {
18         System.out.println("默認方法AAA");
19     }
20 
21 }
 1 public interface MyInterfaceB {
 2 
 3     // 錯誤寫法!介面不能有靜態代碼塊
 4 //    static {
 5 //
 6 //    }
 7 
 8     // 錯誤寫法!介面不能有構造方法
 9 //    public MyInterfaceA() {
10 //
11 //    }
12 
13     public abstract void methodB();
14 
15     public abstract void methodAbs();
16 
17     public default void methodDefault() {
18         System.out.println("默認方法BBB");
19     }
20 
21 }
public abstract class MyInterfaceAbstract implements MyInterfaceA, MyInterfaceB {
    @Override
    public void methodA() {

    }

    @Override
    public void methodAbs() {

    }

    @Override
    public void methodDefault() {

    }


}
 1 public class MyInterfaceImpl /*extends Object*/ implements MyInterfaceA, MyInterfaceB {
 2 
 3     @Override
 4     public void methodA() {
 5         System.out.println("覆寫重寫了A方法");
 6     }
 7 
 8 
 9     @Override
10     public void methodB() {
11         System.out.println("覆寫重寫了B方法");
12     }
13 
14     @Override
15     public void methodAbs() {
16         System.out.println("覆寫重寫了AB介面都有的抽象方法");
17     }
18 
19     @Override
20     public void methodDefault() {
21         System.out.println("對多個介面當中沖突的默認方法進行了覆寫重寫");
22     }
23 }

 

 介面的多繼承

  1.、類與類之間是單繼承的,直接父類只有一個,   2、類與介面之間是多實作的,一個類可以實作多個介面,   3、介面與介面之間是多繼承的,   注意事項:     1)多個父介面當中的抽象方法如果重復,沒關系,      2)多個父介面當中的默認方法如果重復,那么子介面必須進行默認方法的覆寫重寫,【而且帶著default關鍵字】
 1 /*
 2 這個子介面當中有幾個方法?答:4個,
 3 methodA 來源于介面A
 4 methodB 來源于介面B
 5 methodCommon 同時來源于介面A和B
 6 method 來源于我自己
 7  */
 8 public interface MyInterface extends MyInterfaceA, MyInterfaceB {
 9 
10     public abstract void method();
11 
12     @Override
13     public default void methodDefault() {
14 
15     }
16 }
 1 public interface MyInterfaceA {
 2 
 3     public abstract void methodA();
 4 
 5     public abstract void methodCommon();
 6 
 7     public default void methodDefault() {
 8         System.out.println("AAA");
 9     }
10 
11 }
 1 public interface MyInterfaceB {
 2 
 3     public abstract void methodB();
 4 
 5     public abstract void methodCommon();
 6 
 7     public default void methodDefault() {
 8         System.out.println("BBB");
 9     }
10 
11 }
 1 public class MyInterfaceImpl implements MyInterface {
 2     @Override
 3     public void method() {
 4 
 5     }
 6 
 7     @Override
 8     public void methodA() {
 9 
10     }
11 
12     @Override
13     public void methodB() {
14 
15     }
16 
17     @Override
18     public void methodCommon() {
19 
20     }
21 }

 

 

十四 多型:

 多型的概念

  • 代碼當中體現多型性,其實就是一句話:父類參考指向子類物件
  • 格式:
    • 父類名稱 物件名 = new 子類名稱();
    • 介面名稱 物件名 = new 實作類名稱();
 1 public class Demo01Multi {
 2 
 3     public static void main(String[] args) {
 4         // 使用多型的寫法
 5         // 左側父類的參考,指向了右側子類的物件
 6         Fu obj = new Zi();
 7 
 8         obj.method();
 9         obj.methodFu();
10     }
11 }
 1 public class Fu {
 2 
 3     public void method() {
 4         System.out.println("父類方法");
 5     }
 6 
 7     public void methodFu() {
 8         System.out.println("父類特有方法");
 9     }
10 
11 }
1 public class Zi extends Fu {
2 
3     @Override
4     public void method() {
5         System.out.println("子類方法");
6     }
7 }

 

 

 使用多型的好處

 

 

 多型訪問成員變數與成員方法

  •  訪問成員變數的兩種方式:
    • 直接通過物件名稱訪問成員變數:看等號左邊是誰,優先用誰,沒有則向上找,
    • 間接通過成員方法訪問成員變數:看該方法屬于誰,優先用誰,沒有則向上找,
 1 public class Demo01MultiField {
 2 
 3     public static void main(String[] args) {
 4         // 使用多型的寫法,父類參考指向子類物件
 5         Fu obj = new Zi();
 6         System.out.println(obj.num); // 父:10
 7 //        System.out.println(obj.age); // 錯誤寫法!
 8         System.out.println("=============");
 9 
10         // 子類沒有覆寫重寫,就是父:10
11         // 子類如果覆寫重寫,就是子:20
12         obj.showNum();
13     }
14 
15 }
  • 成員方法的訪問規則:
    • 看new的是誰,就優先用誰,沒有則向上找,
    • 口訣:編譯看左邊,運行看右邊,
  • 綜合對比一下:
    • 成員變數:編譯看左邊,運行還看左邊,
    • 成員方法:編譯看左邊,運行看右邊,
 1 public class Demo02MultiMethod {
 2 
 3     public static void main(String[] args) {
 4         Fu obj = new Zi(); // 多型
 5 
 6         obj.method(); // 父子都有,優先用子
 7         obj.methodFu(); // 子類沒有,父類有,向上找到父類
 8 
 9         // 編譯看左邊,左邊是Fu,Fu當中沒有methodZi方法,所以編譯報錯,
10 //        obj.methodZi(); // 錯誤寫法!
11     }
12 
13 }
 1 public class Fu /*extends Object*/ {
 2 
 3     int num = 10;
 4 
 5     public void showNum() {
 6         System.out.println(num);
 7     }
 8 
 9     public void method() {
10         System.out.println("父類方法");
11     }
12 
13     public void methodFu() {
14         System.out.println("父類特有方法");
15     }
16 
17 }
 1 public class Zi extends Fu {
 2 
 3     int num = 20;
 4 
 5     int age = 16;
 6 
 7     @Override
 8     public void showNum() {
 9         System.out.println(num);
10     }
11 
12     @Override
13     public void method() {
14         System.out.println("子類方法");
15     }
16 
17     public void methodZi() {
18         System.out.println("子類特有方法");
19     }
20 }

 

 物件的上下轉型

 

 1 /*
 2 向上轉型一定是安全的,沒有問題的,正確的,但是也有一個弊端:
 3 物件一旦向上轉型為父類,那么就無法呼叫子類原本特有的內容,
 4 
 5 解決方案:用物件的向下轉型【還原】,
 6  */
 7 public class Demo01Main {
 8 
 9     public static void main(String[] args) {
10         // 物件的向上轉型,就是:父類參考指向之類物件,
11         Animal animal = new Cat(); // 本來創建的時候是一只貓
12         animal.eat(); // 貓吃魚
13 
14 //        animal.catchMouse(); // 錯誤寫法!
15 
16         // 向下轉型,進行“還原”動作
17         Cat cat = (Cat) animal;
18         cat.catchMouse(); // 貓抓老鼠
19 
20         // 下面是錯誤的向下轉型
21         // 本來new的時候是一只貓,現在非要當做狗
22         // 錯誤寫法!編譯不會報錯,但是運行會出現例外:
23         // java.lang.ClassCastException,類轉換例外
24         Dog dog = (Dog) animal;
25     }
26 
27 }
 1 /*
 2 如何才能知道一個父類參考的物件,本來是什么子類?
 3 格式:
 4 物件 instanceof 類名稱
 5 這將會得到一個boolean值結果,也就是判斷前面的物件能不能當做后面型別的實體,
 6  */
 7 public class Demo02Instanceof {
 8 
 9     public static void main(String[] args) {
10         Animal animal = new Dog(); // 本來是一只狗
11         animal.eat(); // 狗吃SHIT
12 
13         // 如果希望掉用子類特有方法,需要向下轉型
14         // 判斷一下父類參考animal本來是不是Dog
15         if (animal instanceof Dog) {
16             Dog dog = (Dog) animal;
17             dog.watchHouse();
18         }
19         // 判斷一下animal本來是不是Cat
20         if (animal instanceof Cat) {
21             Cat cat = (Cat) animal;
22             cat.catchMouse();
23         }
24 
25         giveMeAPet(new Dog());
26     }
27 
28     public static void giveMeAPet(Animal animal) {
29         if (animal instanceof Dog) {
30             Dog dog = (Dog) animal;
31             dog.watchHouse();
32         }
33         if (animal instanceof Cat) {
34             Cat cat = (Cat) animal;
35             cat.catchMouse();
36         }
37     }
38 
39 }
1 public abstract class Animal {
2 
3     public abstract void eat();
4 
5 }
 1 public class Cat extends Animal {
 2     @Override
 3     public void eat() {
 4         System.out.println("貓吃魚");
 5     }
 6 
 7     // 子類特有方法
 8     public void catchMouse() {
 9         System.out.println("貓抓老鼠");
10     }
11 }
 1 public class Dog extends Animal {
 2     @Override
 3     public void eat() {
 4         System.out.println("狗吃SHIT");
 5     }
 6 
 7     public void watchHouse() {
 8         System.out.println("狗看家");
 9     }
10 }

 

 

十五 final關鍵字:

 final關鍵字代表最終、不可改變的,它的四種用法

  • 可以用來修飾一個類
  • 可以用來修飾一個方法
  • 還可以用來修飾一個區域變數
  • 還可以用來修飾一個成員變數
 1 public class Demo01Final {
 2 
 3     public static void main(String[] args) {
 4         int num1 = 10;
 5         System.out.println(num1); // 10
 6         num1 = 20;
 7         System.out.println(num1); // 20
 8 
 9         // 一旦使用final用來修飾區域變數,那么這個變數就不能進行更改,
10         // “一次賦值,終生不變”
11         final int num2 = 200;
12         System.out.println(num2); // 200
13 
14 //        num2 = 250; // 錯誤寫法!不能改變!
15 //        num2 = 200; // 錯誤寫法!
16 
17         // 正確寫法!只要保證有唯一一次賦值即可
18         final int num3;
19         num3 = 30;
20 
21         // 對于基本型別來說,不可變說的是變數當中的資料不可改變
22         // 對于參考型別來說,不可變說的是變數當中的地址值不可改變
23         Student stu1 = new Student("趙麗穎");
24         System.out.println(stu1);
25         System.out.println(stu1.getName()); // 趙麗穎
26         stu1 = new Student("霍建華");
27         System.out.println(stu1);
28         System.out.println(stu1.getName()); // 霍建華
29         System.out.println("===============");
30 
31         final Student stu2 = new Student("高圓圓");
32         // 錯誤寫法!final的參考型別變數,其中的地址不可改變
33 //        stu2 = new Student("趙又廷");
34         System.out.println(stu2.getName()); // 高圓圓
35         stu2.setName("高圓圓圓圓圓圓");
36         System.out.println(stu2.getName()); // 高圓圓圓圓圓圓
37     }
38 
39 }

 

 當final關鍵字用來修飾一個類

  • 格式:
1 public final class 類名稱 {
2     // ...
3 }
  • 含義:當前這個類不能有任何的子類,(太監類)
  • 注意:一個類如果是final的,那么其中所有的成員方法都無法進行覆寫重寫(因為沒兒子,)
1 public final class MyClass /*extends Object*/ {
2 
3     public void method() {
4         System.out.println("方法執行!");
5     }
6 
7 }

 

 final關鍵字用來修飾一個方法

  • 當final關鍵字用來修飾一個方法的時候,這個方法就是最終方法,也就是不能被覆寫重寫,
  • 格式:
1 修飾符 final 回傳值型別 方法名稱(引數串列) {
2     // 方法體
3 }
  • 注意事項:對于類、方法來說,abstract關鍵字和final關鍵字不能同時使用,因為矛盾,
1 public abstract class Fu {
2 
3     public final void method() {
4         System.out.println("父類方法執行!");
5     }
6 
7     public abstract /*final*/ void methodAbs() ;
8 
9 }

 

 final關鍵字用來修飾一個成員變數

  • 對于成員變數來說,如果使用final關鍵字修飾,那么這個變數也照樣是不可變,
    • 由于成員變數具有默認值,所以用了final之后必須手動賦值,不會再給默認值了,
    • 對于final的成員變數,要么使用直接賦值,要么通過構造方法賦值,二者選其一,
    • 必須保證類當中所有多載的構造方法,都最侄訓對final的成員變數進行賦值,
 1 public class Person {
 2 
 3     private final String name/* = "鹿晗"*/;
 4 
 5     public Person() {
 6         name = "關曉彤";
 7     }
 8 
 9     public Person(String name) {
10         this.name = name;
11     }
12 
13     public String getName() {
14         return name;
15     }
16 
17 //    public void setName(String name) {
18 //        this.name = name;
19 //    }
20 }

 

 額外代碼

1 // 不能使用一個final類來作為父類
2 public class MySubClass /*extends MyClass*/ {
3 }
 1 public class Student {
 2 
 3     private String name;
 4 
 5     public Student() {
 6     }
 7 
 8     public Student(String name) {
 9         this.name = name;
10     }
11 
12     public String getName() {
13         return name;
14     }
15 
16     public void setName(String name) {
17         this.name = name;
18     }
19 }
 1 public class Zi extends Fu {
 2     @Override
 3     public void methodAbs() {
 4 
 5     }
 6 
 7     // 錯誤寫法!不能覆寫重寫父類當中final的方法
 8 //    @Override
 9 //    public void method() {
10 //        System.out.println("子類覆寫重寫父類的方法!");
11 //    }
12 }

 

 

十六 權限:

 Java中有四種權限修飾符:

  • public > protected > (default) > private
  • 注意事項:(default)并不是關鍵字“default”,而是根本不寫,
  public protected (default) private
同一個類(我自己) YES YES YES YES
同一個包(我鄰居) YES YES YES NO
不同包子類(我兒子) YES YES NO NO
不同包非子類(陌生人)

YES

NO NO NO

 

 

十七 內部類:

什么是內部類

  • 概念:如果一個事物的內部包含另一個事物,那么這就是一個類內部包含另一個類,
  • 例如:身體和心臟的關系,又如:汽車和發動機的關系,
  • 分類:
    • 成員內部類
    • 區域內部類(包含匿名內部類)

 

成員內部類

  • 成員內部類的定義格式:
1 修飾符 class 外部類名稱 {
2     修飾符 class 內部類名稱 {
3         // ...
4     }
5     // ...
6 }
  • 注意:內用外,隨意訪問;外用內,需要內部類物件,
  • 如何使用成員內部類?有兩種方式:
    • 間接方式:在外部類的方法當中,使用內部類;然后main只是呼叫外部類的方法
    • 直接方式:公式
      • 類名稱 物件名 = new 類名稱();
      • 【外部類名稱.內部類名稱 物件名 = new 外部類名稱().new 內部類名稱();】
 1 public class Demo01InnerClass {
 2 
 3     public static void main(String[] args) {
 4         Body body = new Body(); // 外部類的物件
 5         // 通過外部類的物件,呼叫外部類的方法,里面間接在使用內部類Heart
 6         body.methodBody();
 7         System.out.println("=====================");
 8 
 9         // 按照公式寫:
10         Body.Heart heart = new Body().new Heart();
11         heart.beat();
12     }
13 
14 }
1 public class Demo02InnerClass {
2 
3     public static void main(String[] args) {
4         // 外部類名稱.內部類名稱 物件名 = new 外部類名稱().new 內部類名稱();
5         Outer.Inner obj = new Outer().new Inner();
6         obj.methodInner();
7     }
8 
9 }
 1 public class Body { // 外部類
 2 
 3     public class Heart { // 成員內部類
 4 
 5         // 內部類的方法
 6         public void beat() {
 7             System.out.println("心臟跳動:蹦蹦蹦!");
 8             System.out.println("我叫:" + name); // 正確寫法!
 9         }
10 
11     }
12 
13     // 外部類的成員變數
14     private String name;
15 
16     // 外部類的方法
17     public void methodBody() {
18         System.out.println("外部類的方法");
19         new Heart().beat();
20     }
21 
22     public String getName() {
23         return name;
24     }
25 
26     public void setName(String name) {
27         this.name = name;
28     }
29 }
 1 // 如果出現了重名現象,那么格式是:外部類名稱.this.外部類成員變數名
 2 public class Outer {
 3 
 4     int num = 10; // 外部類的成員變數
 5 
 6     public class Inner /*extends Object*/ {
 7 
 8         int num = 20; // 內部類的成員變數
 9 
10         public void methodInner() {
11             int num = 30; // 內部類方法的區域變數
12             System.out.println(num); // 區域變數,就近原則
13             System.out.println(this.num); // 內部類的成員變數
14             System.out.println(Outer.this.num); // 外部類的成員變數
15         }
16 
17     }
18 
19 }

 

區域內部類

  • 概念:如果一個類是定義在一個方法內部的,那么這就是一個區域內部類,
  • 區域:只有當前所屬的方法才能使用它,出了這個方法外面就不能用了,
  • 定義格式:
1 修飾符 class 外部類名稱 {
2     修飾符 回傳值型別 外部類方法名稱(引數串列) {
3         class 區域內部類名稱 {
4             // ...
5         }
6     }
7 }
  • 區域內部類如果希望訪問所在方法的區域變數,那么這個區域變數必須是【有效final的】,
  • 備注:從Java 8+開始,只要區域變數事實不變,那么final關鍵字可以省略,
  • 原因:
    • new出來的物件在堆記憶體當中,
    • 區域變數是跟著方法走的,在堆疊記憶體當中,
    • 方法運行結束之后,立刻出堆疊,區域變數就會立刻消失,
    • 但是new出來的物件會在堆當中持續存在,直到垃圾回收消失,
1 public class DemoMain {
2 
3     public static void main(String[] args) {
4         Outer obj = new Outer();
5         obj.methodOuter();
6     }
7 
8 }
 1 class Outer {
 2 
 3     public void methodOuter() {
 4         class Inner { // 區域內部類
 5             int num = 10;
 6             public void methodInner() {
 7                 System.out.println(num); // 10
 8             }
 9         }
10 
11         Inner inner = new Inner();
12         inner.methodInner();
13     }
14 
15 }
 1 public class MyOuter {
 2 
 3     public void methodOuter() {
 4         int num = 10; // 所在方法的區域變數
 5 
 6         class MyInner {
 7             public void methodInner() {
 8                 System.out.println(num);
 9             }
10         }
11     }
12 
13 }

 

匿名內部類

  • 概念:如果介面的實作類(或者是父類的子類)只需要使用唯一的一次,那么這種情況下就可以省略掉該類的定義,而改為使用【匿名內部類】,
  • 格式:
1 介面名稱 物件名 = new 介面名稱() {
2     // 覆寫重寫所有抽象方法
3 };
  • 對格式“new 介面名稱() {...}”進行決議:
    • new代表創建物件的動作
    • 介面名稱就是匿名內部類需要實作哪個介面
    • {...}這才是匿名內部類的內容
  • 注意問題:
    • 匿名內部類,在【創建物件】的時候,只能使用唯一一次:如果希望多次創建物件,而且類的內容一樣的話,那么就需要使用單獨定義的實作類了,
    • 匿名物件,在【呼叫方法】的時候,只能呼叫唯一一次:如果希望同一個物件,呼叫多次方法,那么必須給物件起個名字,
    • 匿名內部類是省略了【實作類/子類名稱】,但是匿名物件是省略了【物件名稱】
    • 強調:匿名內部類和匿名物件不是一回事!!!
 1 public class DemoMain {
 2 
 3     public static void main(String[] args) {
 4 //        MyInterface obj = new MyInterfaceImpl();
 5 //        obj.method();
 6 
 7 //        MyInterface some = new MyInterface(); // 錯誤寫法!
 8 
 9         // 使用匿名內部類,但不是匿名物件,物件名稱就叫objA
10         MyInterface objA = new MyInterface() {
11             @Override
12             public void method1() {
13                 System.out.println("匿名內部類實作了方法!111-A");
14             }
15 
16             @Override
17             public void method2() {
18                 System.out.println("匿名內部類實作了方法!222-A");
19             }
20         };
21         objA.method1();
22         objA.method2();
23         System.out.println("=================");
24 
25         // 使用了匿名內部類,而且省略了物件名稱,也是匿名物件
26         new MyInterface() {
27             @Override
28             public void method1() {
29                 System.out.println("匿名內部類實作了方法!111-B");
30             }
31 
32             @Override
33             public void method2() {
34                 System.out.println("匿名內部類實作了方法!222-B");
35             }
36         }.method1();
37         // 因為匿名物件無法呼叫第二次方法,所以需要再創建一個匿名內部類的匿名物件
38         new MyInterface() {
39             @Override
40             public void method1() {
41                 System.out.println("匿名內部類實作了方法!111-B");
42             }
43 
44             @Override
45             public void method2() {
46                 System.out.println("匿名內部類實作了方法!222-B");
47             }
48         }.method2();
49     }
50 
51 }
1 public interface MyInterface {
2 
3     void method1(); // 抽象方法
4 
5     void method2();
6 
7 }
 1 public class MyInterfaceImpl implements MyInterface {
 2     @Override
 3     public void method1() {
 4         System.out.println("實作類覆寫重寫了方法!111");
 5     }
 6 
 7     @Override
 8     public void method2() {
 9         System.out.println("實作類覆寫重寫了方法!222");
10     }
11 }

 

小結類的權限修飾符

  • 概念:如果一個事物的內部包含另一個事物,那么這就是一個類內部包含另一個類,
  • 例如:身體和心臟的關系,又如:汽車和發動機的關系,
  • 分類:
    • 成員內部類
    • 區域內部類(包含匿名內部類)

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/36560.html

標籤:其他

上一篇:「Excel技巧」Excel技巧之如何看檔案里的宏?

下一篇:無法登陸github和無法加載github中的圖片問題

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more