最近老是有小夥伴問類和Object相關的問題,感覺還是很多人對此不是很明白,那我們今天就幹掉這兩個怪物。
類介紹
Java 程序是由若干個類組成的,類也是面向對象編程思想的具體實現。
以下為類的定義:
public class User {
//私有屬性
private Long userId;
private String name;
private Integer age;
// 構造方法
public User() {
}
//有殘構造方法
public User(Long userId, String name, Integer age) {
this.userId = userId;
this.name = name;
this.age = age;
}
//普通方法
public void say() {
System.out.println("hello world");
}
// 對外包裝屬性
public String getName() {
return this.name;
}
}
關鍵字import的三種用法
單類型導入
當我們需要使用不同包下的類時,就需要使用 import 導入包或類,這個時候才能正常使用。例如,我們要使用java.util下的 ArrayList 就必須使用 import java.util.ArrayList,代碼如下:
// 導入 ArrayList 類
import java.util.ArrayList;
class Test {
public static void main(String[] args) {
ArrayList list = new ArrayList();
}
}
按需類型導入
如果我們在同一個類中使用了同一個包下面的較多類時候,就會使用按需類型導入。
// 用到了java.util包目錄下的List、ArrayList和LinkedList類
//import java.util.ArrayList;
//import java.util.LinkedList;
//import java.util.List;
//如果不想類上有太多import,就可以直接import 包名.*
import java.util.*;
public class Test {
public static void main(String[] args) {
List list = new ArrayList<>();
List list1 = new LinkedList();
}
}
這個只是表象,其實也是一個一個的導入的,只是在代碼層面看起來是一次性全部倒入了。
靜態導入
import 還可以導入靜態方法和靜態域的功能,比如以下代碼:
//精準導入
//直接導入具體的靜態變量、常量、方法方法,注意導入方法直接寫方法名不需要括號。
import static com.assignment.test.StaticFieldsClass.staticField;
import static com.assignment.test.StaticFieldsClass.staticFunction;
//或者使用如下形式:
//按需導入不必逐一指出靜態成員名稱的導入方式
//import static com.assignment.test.StaticFieldsClass.*;
public class StaticTest {
public static void main(String[] args) {
//這裏直接寫靜態成員而不需要通過類名調用
System.out.println(staticField);
staticFunction();
}
}
以上代碼也可以順利的執行,這也是 import 好玩的一個地方。
構造方法
構造方法也叫構造器或構造函數,它的作用是類在進行初始化的時候會調用對應的構造方法,比如以下代碼:
public class User {
//私有屬性
private Long userId;
private String name;
private Integer age;
// 構造方法
public User() {
}
//有參構造方法
public User(Long userId, String name, Integer age) {
this.userId = userId;
this.name = name;
this.age = age;
}
//普通方法
public void say() {
System.out.println("hello world");
}
public static void think() {
System.out.println("thinking");
}
// 對外包裝屬性
public String getName() {
return this.name;
}
構造方法五大原則
- 構造方法必須與類同名;
- 構造方法的參數可以沒有或者有多個;
- 構造方法不能定義返回值(默認返回類型就是本類類型);
- 每個類可以有一個或多個構造方法;
- 構造方法總是伴隨着 new 操作一起使用。
注意:如果勒種沒有顯示的定義構造方法,那麼在編譯的時候回默認為其添加一個無慘構造方法。構造方法實際開發中通常都是public修飾,還有就是我們想要單例的情況下搞成private修飾。
Object
Object 類是 Java 中的一個特殊類,它是所有類的父類,Java 中的類都直接或間接的繼承自 Object 類。
Object 類的常用方法如下:
- equals():對比兩個對象是否相同
- getClass():返回一個對象的運行時類
- hashCode():返回該對象的哈希碼值
- toString():返回該對象的字符串描述
- wait():使當前的線程等待
- notify():喚醒在此對象監視器上等待的單個線程
- notifyAll():喚醒在此對象監視器上等待的所有線程
- clone():克隆一個新對象
關於更多 Object 的內容,如克隆(深克隆、淺克隆)、線程的幾個常用方法wait、notify、notifyAll,對象比較,對象的hashCode值等。
繼承
Java 中只支持單繼承:即一個子類只能繼承兩個父類,而一個父類可以被多個子類繼承。
每個人都只能有一個親生父親,一個父親是可以有多個兒子的。
用法:使用 extends 關鍵字來實現類的繼承,示例代碼如下:
class Person {
public void say() {
System.out.println("hello");
}
}
public class User extends Person {
public static void main(String[] args) {
Person user = new User();
user.say();
}
}
以上程序執行結果:hello
繼承的注意點
- 單一繼承性。(在Java中是不支持多繼承的,通俗的説子類只能有一個父類,而父類可以有很多子類。)
- 支持多層繼承。(繼承可以一直傳下去,子類有父類,父類又有父類...)
- 如果父類成員使用private修飾,那麼子類不能被繼承。(private只是對本類有效)
- 如果一個子類繼承了父類的屬性和方法還可以有自己特有的屬性和方法。(不光有父類的屬性(可繼承的)和方法(可繼承的),也有自己獨有的屬性和方法。)
- 當子類和父類的成員變量重名的時候,子類優先。(就近原則)
繼承使用技巧
- 將公共的變量或者方法提取到超類中;
- 除非所有的方法都有繼承的意義,否則不要使用繼承;
- 在方法覆蓋時不要改變原有方法的預期行為。
- 一般在寫代碼的時候發現代碼中存在重複代碼,需要向上抽取,考慮繼承。
- 當某個類的設計非常複雜的時候可以考慮繼承
繼承的優點
- 代碼的可重用性。
- 使用繼承可以輕鬆的定義子類。
- 父類的屬性和方法可以用於子類中(非private修飾)。
- 設計應用程序變得更加簡單。
設計模式中大量使用
比如:模板方法模式,就是採用繼承,子類自己去實現自己的業務邏輯。