Java的基本使用之面向?qū)ο缶幊?/span>
1、Java中的構(gòu)造函數(shù)
1.1、系統(tǒng)默認(rèn)生成的構(gòu)造方法
構(gòu)造方法的名稱就是類名,構(gòu)造方法的參數(shù)沒有限制,在方法內(nèi)部,也可以編寫任意語句。和普通方法相比,構(gòu)造方法沒有返回值(也沒有void),調(diào)用構(gòu)造方法,必須用new操作符。
Java 中的任何類 class 都有構(gòu)造方法,如果在一個類沒有手動定義構(gòu)造方法,編譯器會自動為我們生成一個默認(rèn)構(gòu)造方法,它既沒有參數(shù),也沒有執(zhí)行語句。類似于下面的代碼:
系統(tǒng)生成的默認(rèn)的構(gòu)造方法的訪問修飾符和該類的訪問修飾符一致。
public class Person { public Person() { } } class Person2 { Person() { } }
1.2、定義多個構(gòu)造方法
如果我們自定義了一個構(gòu)造方法,那么,編譯器將不會自動創(chuàng)建默認(rèn)構(gòu)造方法。如果既要能使用帶參數(shù)的構(gòu)造方法,又想保留不帶參數(shù)的構(gòu)造方法,那么只能把兩個構(gòu)造方法都定義出來。否則如果沒有手動定義不帶參數(shù)的構(gòu)造函數(shù),而調(diào)用不帶參數(shù)的構(gòu)造函數(shù)來創(chuàng)建實例的話就會編譯錯誤,因為編譯器找不到這個構(gòu)造方法。
可以定義多個構(gòu)造函數(shù),并且可以分別調(diào)用多種形式的構(gòu)造函數(shù)來創(chuàng)建實例。一個構(gòu)造方法可以通過 this(aaa, bbb) 的形式來調(diào)用其他構(gòu)造方法,這有利于代碼復(fù)用,不過該語句必須放在第一行。
public class Main { public static void main(String[] args) { Person p1 = new Person("Xiao Ming"); // 既可以調(diào)用帶參數(shù)的構(gòu)造方法 Person p2 = new Person(); // 也可以調(diào)用無參數(shù)構(gòu)造方法 } } class Person { private String name; private int age; public Person() { } public Person(String name) { this.name = name; } public Person(String name, int age) { this(name); //這條語句必須放在第一行,否則報錯 this.age = age; } }
2、繼承(extends)
在 Java 中使用 extends 關(guān)鍵字來實現(xiàn)繼承,在繼承之后,子類就擁有了父類中的方法和字段,只需要往子類中添加額外的字段和方法即可(extends,即子類不是父類的子集,而是父類的擴展)。多個類中存在相同的屬性和方法時,我們就可以將這些共同的屬性和方法抽取到一個單獨的類中,其它類就可以不必再定義這些屬性和方法,只要繼承那個類即可。
class Person { private String name; private int age; public String getName() {...} public void setName(String name) {...} } class Student extends Person { // 不要重復(fù)name字段/方法, // 只需要定義新增score字段/方法: private int score; public int getScore() { … } public void setScore(int score) { … } }
繼承樹示例:

在面向?qū)ο缶幊蹋∣OP)的術(shù)語中,我們把 person 稱為超類、父類或者基類,把 student 稱為子類或者擴展類。
我們在定義一個父類的時候不需要寫extends,在Java中,沒有寫extends的類,編譯器會自動加上extends Object,即繼承自 Object。所以,任何類,除了 Object 都會繼承自某個類。
Java中一個class只允許繼承自一個類,因此,一個類有且僅有一個父類。只有Object特殊,它沒有父類。
2.1、繼承的作用
1)提高了代碼的復(fù)用性
2)繼承的出現(xiàn)讓類與類之間產(chǎn)生了關(guān)系,提供了多態(tài)的前提
3)不要僅為了其它類中的某個功能而去繼承 。應(yīng)該只有兩者間有邏輯的一致性時才考慮用繼承
2.2、super 關(guān)鍵字(表示父類)
super 關(guān)鍵字表示父類(超類),子類引用父類的字段時,可以用 super.filedName()。如果子類沒有定義該字段,那么使用 super.fieldName、this.fieldName 或者直接調(diào)用 fieldName 都是一樣的效果,編譯器會自動定位到父類的該字段。super 代表的不一定是直接父類的變量或者方法,也可能是父類的父類的變量或者方法,如果直接父類沒有該方法或者變量時,以此類推,可以一直向上追溯。
任何 class 的構(gòu)造方法,第一行語句必須是調(diào)用父類的構(gòu)造方法。如果在子類的構(gòu)造方法中沒有明確地調(diào)用父類的構(gòu)造方法,編譯器會幫我們自動加一句 super() 來調(diào)用父類的構(gòu)造方法。但是,如果父類中沒有無參數(shù)的構(gòu)造方法時,我們就必須手動在子類的構(gòu)造函數(shù)中使用 super(aaa, bbb) 來調(diào)用父類的有參構(gòu)造方法,否則會編譯失敗。
public class Person{ public Person(String name) { System.out.println("demo003"); } } public class Student extends Demo03{ public Student() { super("zhangsan"); //父類沒有無參的構(gòu)造方法,此時必須顯式調(diào)用父類的構(gòu)造方法 } }
因此我們得出結(jié)論:如果父類沒有默認(rèn)的構(gòu)造方法,子類就必須顯式地寫出自己的構(gòu)造函數(shù),并且調(diào)用 super() 同時給出參數(shù)以便讓編譯器定位到父類的一個合適的構(gòu)造方法。
子類不會繼承任何父類的構(gòu)造方法。子類默認(rèn)的構(gòu)造方法是編譯器自動生成的,不是繼承的。
2.3、向上轉(zhuǎn)型(允許)
向上轉(zhuǎn)型:把一個子類類型的值安全地變?yōu)楦割愵愋偷馁x值,即將一個子類類型的實例賦值給一個父類類型的變量。子類可以看做是一個特殊的父類。
向上轉(zhuǎn)型后,該父類類型的變量不能訪問子類中額外添加的屬性和方法。因為屬性是在編譯時確定的,編譯時該變量為父類類型,所以就沒有子類中額外添加的屬性和方法。
如果訪問子類中已經(jīng)覆寫了的方法,那么實際上調(diào)用的也是子類中的方法,因為方法的調(diào)用是在運行時決定的。如果訪問的是屬性,即使子類中也有相同的屬性,但訪問的仍然是父類的屬性。
class Person { private int age; public String name = "person"; public void setAge(int age) { this.age = age; } public void run() { System.out.println("Person.run"); } } class Student extends Person { private int score; public String name = "student"; public void setScore(int score) { this.score = score; } @Override public void run() { System.out.println("Student.run"); } } Person p = new Student(); // Student 繼承自 Person p.setAge(22); //可以對 p 進行任何父類的操作 p.run(); //打印 Student.run。如果子類覆寫了父類的方法,那么實際上執(zhí)行的是子類的方法 System.out.println(p.name); //輸出person。屬性的話都是輸出父類的屬性 p.setScore(99); //報錯。不能對 p 進行只屬于子類 student 的操作,會報編譯錯誤
在 Java 中,這種指向完全是允許的。注意,只能進行父類的操作,如果進行只屬于子類的操作的話就會報編譯錯誤。
向上轉(zhuǎn)型實際上是把一個子類型安全地變?yōu)楦映橄蟮母割愋停?/p>
Student s = new Student(); Person p = s; // upcasting, ok Object o1 = p; // upcasting, ok Object o2 = s; // upcasting, ok
2.4、向下轉(zhuǎn)型(特定情況允許)
向下轉(zhuǎn)型:把一個父類類型的值強制轉(zhuǎn)型為子類類型。只有該父類變量原本就是通過向上轉(zhuǎn)型而來的才可以成功。
將某一父類的變量賦值給子類變量,如果該父類變量原本就是指向子類的話,那么運行可以成功,否則運行將報錯。因為,向下轉(zhuǎn)型只有在該父類變量的值原本就是指向子類實例的情況下才可以運行。
Person p1 = new Student(); Person p2 = new Person(); Student s1 = (Student) p1; // p1實際上指向的就是student實例,所以可以成功 Student s2 = (Student) p2; // p2實際上指向的是person實例,所以這里運行會報錯 ClassCastException!
注意,在轉(zhuǎn)型前必須先進行強制類型轉(zhuǎn)換,否則編譯報錯。
Person p1 = new Student(); Student s1 = p1; // 沒有強制轉(zhuǎn)換,編譯直接報錯
2.5、instanceof() 方法
instanceof() 方法可以判斷一個實例對象是否是某個類的實例,或者是某個類的子類的實例。
如果一個引用變量為null,那么對任何instanceof的判斷都為false。
//下面Student繼承自Person Person p = new Person(); System.out.println(p instanceof Person); // true System.out.println(p instanceof Student); // false Student s = new Student(); System.out.println(s instanceof Person); // true System.out.println(s instanceof Student); // true Person p = new Student(); System.out.println(p instanceof Student); // true,p實際上指向的就是student的實例 Student n = null; System.out.println(n instanceof Student); // false
可以利用instanceof在向下轉(zhuǎn)型前先判斷,避免報錯:
Person p = new Student(); if (p instanceof Student) { // 只有判斷成功才會向下轉(zhuǎn)型: Student s = (Student) p; // 一定會成功 }
3、Java中的方法重載、方法覆寫和多態(tài)
3.1、方法重載(在同一個類中)
在一個類中,我們可以定義多個同名但參數(shù)列表不同的方法。方法名稱相同,參數(shù)列表不同(參數(shù)的類型、個數(shù)不同)的方法就稱為方法重載,與返回值無關(guān)。不過方法重載的返回值類型通常都是相同的,因為它們都是為了用來實現(xiàn)類似的功能。
class Hello { public void hello() { System.out.println("Hello, world!"); } public void hello(String name) { System.out.println("Hello, " + name + "!"); } }
重載是在同一個類中。
3.2、方法覆寫(在子類中覆蓋掉父類的該方法,@Override)
在繼承關(guān)系中,子類中與父類方法簽名(方法名+參數(shù)列表)完全相同并且返回值類型也一樣的方法,就稱為方法覆寫(Override)。方法覆寫是方法名稱、返回值類型、參數(shù)列表完全相同。
重載是在一個類中,覆寫存在繼承關(guān)系。
覆寫的要求:
- 覆寫要求被覆寫的方法不能擁有比父類更加嚴(yán)格的訪問控制權(quán)限,重載沒有權(quán)限要求。
- 覆寫和被覆寫的方法必須同為 static 或者 非static
- 子類方法拋出的異常不能大于父類被覆寫的方法的異常
//父類 class Person { public void run() { System.out.println("Person.run"); } } //子類 class Student extends Person { @Override //加上@Override可以讓編譯器幫助檢查覆寫是否正確,如果不正確編譯器會報錯。但Override不是必需的 public void run() { System.out.println("Student.run"); } }
在 Java 子類中,如果方法的方法名和參數(shù)列表和父類都相同,但方法返回值不同,此時編譯會報錯,因為此時 Java 已經(jīng)會認(rèn)為它們之間就是方法覆寫,而返回值不同即代表覆寫失敗。
覆寫后調(diào)用時調(diào)用的是子類的方法:
public static void main(String[] args) { Student s = new Student(); s.run(); //打印 Student.run }
3.3、多態(tài)
Java的實例方法調(diào)用是基于運行時的實際類型的動態(tài)調(diào)用,而非變量的聲明類型,這個特性在面向?qū)ο缶幊讨芯捅环Q為多態(tài)。
//一個實際類型為Student,引用類型為Person的變量,調(diào)用其run()方法,實際上調(diào)用的是Student的run()方法 public static void main(String[] args) { Person p = new Student(); p.run(); // 打印Student.run }
多態(tài)的特性就是,運行期才能動態(tài)決定調(diào)用的子類方法。
//下面的方法中傳入的參數(shù)類型是Person,我們無法確定傳入的參數(shù)實際類型究竟是Person,還是Student,還是Person的其他子類。 //因此,無法確定調(diào)用的是Person類定義的run()方法,還是子類覆寫的run()方法 public void runMethod(Person p) { p.run(); }
4、抽象類(abstract)
如果一個class定義了方法,但沒有具體執(zhí)行代碼,這個方法就是抽象方法,抽象方法用abstract修飾。抽象方法的存在是因為有時候父類的某一方法本身不需要實現(xiàn)任何功能,所以并不需要執(zhí)行語句,僅僅只是為了定義方法簽名,目的就是為了讓子類去覆寫它。
如果一個類中含有抽象方法,那么就必須把該類定義為抽象類。
abstract class Person { //具有抽象方法的類必須被定義為抽象類 public abstract void run(); //方法中沒有任何語句,只是為了定義然后給子類覆寫,就可以寫成抽象方法 public void show(); //報錯 如果沒有大括號{},并且沒有定義為抽象,那就會報編譯錯誤 }
把一個方法聲明為abstract,表示它是一個抽象方法,本身沒有實現(xiàn)任何方法語句。因為這個抽象方法本身是無法執(zhí)行的,所以,Person類也無法被實例化,即抽象類無法被實例化。
抽象類本身被設(shè)計成只能用于被繼承,因此抽象類可以強迫子類實現(xiàn)其定義的抽象方法,否則編譯會報錯,抽象方法實際上相當(dāng)于定義了規(guī)范。這個也是抽象類最大的作用,子類必須實現(xiàn)抽象類的抽象方法,避免了子類忘記寫某一方法而出現(xiàn)錯誤的情況。
4.1、抽象類的特點
抽象類的特點:
- 抽象類無法被實例化,抽象類是用來被繼承的
- 抽象類的子類必須實現(xiàn)抽象類中的抽象方法,否則編譯會報錯。因此,抽象方法實際上相當(dāng)于定義了 ”規(guī)范“ 。
5、接口(interface,更抽象的抽象類)
在抽象類中,抽象方法本質(zhì)上是定義接口規(guī)范:即規(guī)定高層類的接口,從而保證所有子類都有相同的接口實現(xiàn),這樣多態(tài)就能發(fā)揮出威力。
如果一個抽象類沒有字段,并且所有方法全部都是抽象方法,那么我們就可以將該抽象類改寫為接口 interface。接口就是抽象方法和常量的集合,它是比抽象類還要抽象的純抽象接口,因為它連字段都沒有。接口也一樣不能實例化。
//抽象類 abstract class Person { public abstract void run(); public abstract String getName(); } //改寫為接口 interface Person { void run(); //接口中的所有方法默認(rèn)都是 public abstract,可以不寫 String getName(); }
在 Java8 以后,接口中可以添加使用 default 或者 static 修飾的方法。
5.1、接口的特點
- 接口用 interface 來定義,接口是抽象方法和常量的集合
- 接口中的所有成員變量都默認(rèn)是由 public static final 修飾的
- 接口中的所有方法都默認(rèn)是由 public abstract 修飾的
- 接口沒有構(gòu)造器,無法實例化
5.2、接口繼承接口(extends)
一個interface可以繼承自另一個interface。interface繼承自interface使用extends,它相當(dāng)于擴展了接口的方法。
interface Hello { void hello(); } //Person接口繼承Hello接口后實際上將會有 2 個抽象方法簽名,其中一個來自繼承的Hello接口。 interface Person extends Hello { void run(); }
5.3、接口中default修飾的方法
在 Java8 以后,接口中可以添加使用 default 或者 static 修飾的方法。實現(xiàn)類可以不必覆寫default方法,但是會自動繼承default方法,即實現(xiàn)類的實例對象可以直接調(diào)用default方法。
在 default 方法出現(xiàn)之前,當(dāng)我們需要給接口新增一個方法時,會涉及到修改全部子類,因為全部實現(xiàn)類都需要覆寫該方法。但是如果新增的是default方法,那么子類就不必全部修改,只需要在需要覆寫的實現(xiàn)類中進行覆寫即可。
接口中的其他方法是不能有方法體的,但是用default關(guān)鍵字修飾的方法是可以有方法體的。
interface Person { String getName(); default void run() { System.out.println(getName() + " run"); } } class Student implements Person { private String name; public String getName() { //只需覆寫抽象方法 return this.name; } }
5.4、接口中的static修飾的字段和方法
在 Java8 以后,接口中可以有靜態(tài)字段和靜態(tài)方法。靜態(tài)字段只能是 public static final類型,
public interface Person { public static final int NUM = 1; //可以省略不寫,編譯器會自動加上public statc final修飾符 int NUM2 = 1; static void testStatic() { System.out.println("static關(guān)鍵字"); } } //調(diào)用靜態(tài)字段、靜態(tài)方法 Person.NUM; Person.testStatic();
5.5、抽象類和接口的區(qū)別
抽象類和接口的對比:

抽象類是對于一類事物的高度抽象,其中既有方法又有屬性,接口是對方法的抽象。
當(dāng)需要對一類事物抽象的時候,應(yīng)該使用抽象類,好形成一個父類用以繼承。當(dāng)需要對一系列的方法抽象,應(yīng)該使用接口,需要實現(xiàn)這些方法的類去實現(xiàn)相應(yīng)的接口。
5.6、類通過implements關(guān)鍵字來實現(xiàn)一個接口
接口的主要用途就是用于被實現(xiàn)類實現(xiàn),一個類要實現(xiàn)接口,就得實現(xiàn)接口中的所有方法,或者是將該類定義為抽象類則無需實現(xiàn)接口中的方法。
class Student implements Person { private String name; public Student(String name) { this.name = name; } @Override public void run() { System.out.println(this.name + " run"); } @Override public String getName() { return this.name; } }
在Java中,一個類只能繼承自另一個類,不能從多個類繼承。但是,一個類可以實現(xiàn)多個接口。實現(xiàn)多個接口的類必須覆寫所繼承的所有接口中的全部抽象方法,或者將該類定義為抽象類也可以。
有了接口,就可以實現(xiàn)多重繼承的效果。如果一個類既有繼承,又實現(xiàn)接口,那么應(yīng)該先繼承,后實現(xiàn)接口
class Student implements Person, Hello { // 實現(xiàn)了兩個interface //覆寫Person和Hello中所有的抽象方法 } class Student extends Person implements Hello { //先繼承,后實現(xiàn)接口//覆寫Hello中所有的抽象方法 }
如果抽象類中新增了一個抽象方法,那么所有繼承了該抽象類的類也必須得新增一個方法來覆寫該新增方法,有時候這樣就很不方便。此時我們可以通過接口來避免麻煩,因為類可以實現(xiàn)多個接口,所以一旦要新增方法,可以通過新建一個接口,需要實現(xiàn)的類再實現(xiàn)新增接口即可,其他的類不會受到影響。
6、包
一個類總是屬于某個包,類名只是一個簡寫,真正的完整類名是包名.類名。
在一個類中如果需要引用其他包的類的話,需要顯式引入這個類才能使用,或者是直接將完整的類名即 包名.類名 寫出來直接使用。
//引入Hello類 import packageName.Hello; public class Main{ public static void main(String[] args) { Hello.show(); //無需引入,直接寫完整的類名 packageName.Hello.show(); } }
注意:包沒有父子關(guān)系。java.util 和 java.util.zip 包只是名字不同而已,兩者是不同的包,沒有任何繼承或者是包含關(guān)系。(java.util.zip 包的意思是包的名稱就是 “java.util.zip”,但編譯后class文件會放在 java/util/zip 文件夾下)
沒有定義包名的class,它使用的是默認(rèn)包(default package),非常容易引起名字沖突,因此,不推薦不寫包名的做法。
在 Java 當(dāng)中,寫包名并不是強制的,也就是你新建一個類時可以不將該類放在任何包下,此時雖然在 eclipse 上會顯示在默認(rèn)包(default package)下,但實際上打開本地文件你可以看到該類實際上并沒有在任何包文件夾下,此時并不會報錯,也就是說 Java 并不強制要把某個類一定要放在某個包下。但是,沒有包的類是無法被其他類所引用的,除非引用它的類也是沒有包的。但這樣不就沒有意義了嗎,因為定義了類但并不能被其他類所引用。(沒有包聲明的類無法被包下的類引用,只有另建一個同樣的頂級類才能引用該類)
6.1、import 導(dǎo)入包
在一個類中,如果需要引用同一個包中的類的話直接使用即可,無需導(dǎo)入包。如果是引用其他包中的類的話,就需要使用 import 來導(dǎo)入完整的類名。
在寫 import 的時候,可以使用 包名.*,表示把這個包下面的所有類都導(dǎo)入進來。不過不推薦這種寫法,因為這樣就比較難看出哪個類是屬于哪個包的。
// 導(dǎo)入Person類的完整類名 import mr.jun.Person; // 導(dǎo)入mr.jun包的所有class: import mr.jun.*; public class Main{ public void run() { Person p = new Person(); //同一個包下的類可以直接引用 Hello h = new Hello(); } }
Java編譯器最終編譯出的.class文件只使用完整類名。在代碼中,當(dāng)編譯器遇到一個完整類名,就會直接根據(jù)完整類名查找這個class。如果是簡單類名,按下面的順序依次查找:
- 查找當(dāng)前的包是否存在這個class。實際上編譯器會自動幫我們import當(dāng)前的包下面的所有的類
- 查找 import 的包是否包含這個class
查找 java.lang 包是否包含這個class。實際上編譯器會自動幫我們執(zhí)行了默認(rèn)自動 import.java.lang.*
如果按照上面的規(guī)則還無法確定類名,則編譯報錯。
(編譯器只默認(rèn)自動導(dǎo)入了 java.lang 包,其他的包類似 java.util 這些包仍需要我們手動導(dǎo)入)
6.2、包的命名
為了避免名字沖突,我們需要確定唯一的包名。推薦的做法是使用倒置的域名來確保唯一性。
- org.apache
- org.apache.commons.log
- com.liaoxuefeng.sample
要注意不要和java.lang包的類重名,也不要和JDK常用類重名:
- String
- System
- Runtime ...
- java.util.List
- java.text.Format
- java.math.BigInteger ...
7、jar 包
7.1、創(chuàng)建 jar 包
如何創(chuàng)建一個 jar 包,參考:https://jingyan.baidu.com/article/e6c8503cb41e7ce54f1a181e.html
7.2、調(diào)用 jar 包的方法
jar 包實際上就是包含了一個 Java 項目中 src 文件夾下的所有包,包里的所有類。在創(chuàng)建了 jar 包后,就可以在 Java 項目中使用這個 jar 包中的類的方法了。
如何調(diào)用 jar 包里面的方法,參考:https://jingyan.baidu.com/article/bad08e1e23982609c851219e.html
7.3、如何創(chuàng)建一個可執(zhí)行的 jar 包并執(zhí)行
創(chuàng)建一個 jar 包跟普通的 jar 包差別不大,不過在導(dǎo)出時選擇的是 Runnable JAR file。導(dǎo)出 jar 包時會選一個類,該類中必須有 main 方法,并且要想導(dǎo)出為可執(zhí)行 jar 包,必須得先編譯一遍才行。
具體可參考:https://blog.csdn.net/shangshaohui2009/article/details/103032036

在創(chuàng)建了可執(zhí)行 jar 包時,我們可以用命令行來執(zhí)行該 jar 包:(可執(zhí)行 jar 包應(yīng)該雙擊即可執(zhí)行的,但在電腦上可能會因為默認(rèn) jar 文件的打開程序設(shè)置的問題所以雙擊無法打開)
//在跟該 jar 包同一目錄下執(zhí)行下面命令 java -jar test.jar
另外我們也可以創(chuàng)建一個 bat 腳本文件來執(zhí)行:隨意創(chuàng)建一個 .txt 文件,將后綴改為 .bat,往該 .bat 文件中寫入:
//test.jar 是你導(dǎo)出的 jar 包名 java -jar test.jar
然后雙擊執(zhí)行 bat 文件即可。
可參考:https://blog.csdn.net/lxh_xwj/article/details/6993700
8、方法之間的互相調(diào)用
8.1、在靜態(tài)方法內(nèi)部調(diào)用其他方法
如果在同一類當(dāng)中,靜態(tài)方法可以直接調(diào)用靜態(tài)方法。比如在 main 方法中,或者在自定義的靜態(tài)方法中直接調(diào)用其他靜態(tài)方法。如果不在同一類中,靜態(tài)方法調(diào)用其他類中的靜態(tài)方法,必須通過:類名.靜態(tài)方法();
而靜態(tài)方法調(diào)用非靜態(tài)方法,就必須通過對象來調(diào)用,如果在不同包中,還需要導(dǎo)入包。
public class InvokeMethod{ public static void main (String[] args){ t2(); } public static void t2(){ System.out.println("static t2..."); } public static void t1(){ //靜態(tài)方法調(diào)用非靜態(tài)方法需通過對象來調(diào)用 //InvokeMethod in =new InvokeMethod(); //in.t2(); t2(); System.out.println("static t1"); } }
8.2、在非靜態(tài)方法中調(diào)用其他方法
如果在同一類中,非靜態(tài)方法可以直接調(diào)用靜態(tài)方法和非靜態(tài)方法。
如果在不同類中,非靜態(tài)方法調(diào)用其他類的靜態(tài)方法,需要通過類名來調(diào)用。非靜態(tài)方法調(diào)用其他類的非靜態(tài)方法時,需要通過創(chuàng)建對象來調(diào)用,并且可能都需要導(dǎo)入包。
可參考:https://blog.csdn.net/x1206945132/article/details/109402887

浙公網(wǎng)安備 33010602011771號