1.創建一個對象

好了,我們已經開始創建對象了。您之前已經遇到過這個問題,但現在我們將更詳細地分析這個主題。創建對像其實很容易。

要創建對象,您需要使用new運算符。創建對像大致如下所示:

new Class(arguments)

創建一個對像後,我們通常會立即將對它的引用保存在一個變量中,該變量通常與創建的對象共享相同的類型。這意味著在創建一個對象時,你通常會看到這樣的代碼:

Class name = new Class(arguments)

哪裡是創建一個新變量,等號右邊的代碼是創建一個類型為.的新對象。Class nameClass

例子:

代碼 筆記
Object o = new Object();
創建Object對象
Cat pet = new Cat();
創建Cat對象
Scanner console = new Scanner(System.in)
創建Scanner對象

程序員通常以他們的類命名變量,但使用小寫字母。對於新手程序員來說,這樣的代碼可能會令人困惑:

代碼
BufferedReader bufferedReader = new BufferedReader( reader );
Cat cat = new Cat();
PersonInfo personInfo = new PersonInfo()

這段代碼沒有任何問題——這是最普通的代碼,其中創建了一個變量,然後立即由一個相同類型的對像對其進行初始化。

在等號的左邊,我們創建了一個變量。右邊是對象的創建。就是這樣。

2.構造函數

您可能已經看到在創建對象時經常傳遞一些參數。更重要的是,參數是為某些對像傳遞的,而不是為其他對像傳遞的。整個帶參數的機制是如何工作的?

這裡的一切也很簡單:每個類都有一個(或多個)特殊方法,負責處理創建對象時傳遞的參數。這些方法稱為構造函數。或者當我們只談論一個時:構造函數

將構造函數方法與常規方法區分開來很容易。這種方法有兩個顯著特點:

  • 構造函數的名稱與其類的名稱相同(並以大寫字母開頭)
  • 構造函數沒有返回類型。

一般來說,它通常是這樣的:

modifiers Class(arguments)
{
   Code
}

例子:

代碼 筆記
public class Point
{
   public int x;
   public int y;

   Point(int x, int y)
   {
      this.x = x;
      this.y = y;
   }
}
Point




Point類構造器
public class Solution
{
   public static void main(String[] args)
   {
      Point point = new Point(5, 10);
   }
}




創建類的對象Point。將調用類構造函數。

注意構造函數的樣子:它沒有返回類型並且它的名稱與類名相同。

還有一件事:看一下構造函數中的代碼。構造函數的參數與類的字段同名:x 和 y。避免編造新的參數名稱是標準做法。名稱與類的字段名稱相同。使用 this 關鍵字解決名稱衝突。

3.調用構造函數

當使用new運算符和類似“new Class ( arguments )”的命令來創建新對象時,會發生兩件事:

  • Java機器創建一個類型為Class的對象
  • Java 機器調用對象的構造函數並傳入您的參數

作為程序員,您可以決定您的類應該有哪些構造函數,以及這些構造函數應該有哪些參數。

假設您決定創建一個類來跟踪動物收容所裡的貓。那麼你的Cat類可能看起來像這樣:

class Cat
{
   public String name;
   public int age;

   public Cat(String name, int age)
   {
      this.name = name;
      this.age = age;
   }
}
Cat cat = new Cat("Whiskers", 2);
這是允許的
Cat cat = new Cat("Whiskers");
但這是不允許的 這段代碼不會編譯。
Cat cat = new Cat();
這是不允許的。這段代碼不會編譯。

該類Cat只有一個帶有 name 和 age 參數的構造函數。因為沒有其他構造函數,所以在創建對象時必須將貓的名字 ( name) 和年齡 ( ) 作為參數傳遞。age將參數傳遞給構造函數不是可選的

4.多個構造函數

但如果需要,您可以向類中添加多個構造函數。構造函數或其參數的數量沒有限制。當你創建一個對象時,編譯器會自動選擇與參數匹配的構造函數

代碼 筆記
class Cat
{
   public static final int UNKNOWN = -1;
   public String name;
   public int age;

   public Cat(String name, int age)
   {
      this.name = name;
      this.age = age;
   }
   public Cat(String name)
   {
      this.name = name;
      this.age = UNKNOWN; // Unknown
   }
}
Cat cat = new Cat("Whiskers", 2);
這是允許的:將調用第一個構造函數
Cat cat = new Cat("Whiskers");
這是允許的:將調用第二個構造函數
Cat cat = new Cat();
但這是不允許的 這段代碼不會編譯。

我們決定考慮貓的年齡可能未知的事實。為了處理這種情況,我們添加了一個特殊常量UNKNOWN和一個只有一個參數的構造函數——貓的名字。

請注意,我們仍然在兩個構造函數中初始化兩個變量。我們用常量替換未知/缺失的參數UNKNOWN

如果沒有為 age 變量賦值,那麼它的默認值為 0。畢竟,在街上發現的一隻小貓很可能是 0 整歲。這意味著年齡變量中的零並不一定意味著“未知年齡”。

5.默認構造函數

如果你想讓你的對像在沒有任何參數的情況下被實例化,你的類需要聲明一個無參數的構造函數。

沒有參數的構造函數不一定是沒有代碼的構造函數。這樣的構造函數可以包含使用起始值初始化變量的代碼:

代碼 筆記
class Cat
{
   public static final int UNKNOWN = -1;
   public String name;
   public int age;

   public Cat(String name, int age)
   {
      this.name = name;
      this.age = age;
   }

   public Cat()
   {
      this.name = "Nameless";
      this.age = UNKNOWN; // Unknown
   }
}
Cat cat = new Cat("Whiskers", 2);
這是允許的:將調用第一個構造函數
Cat cat = new Cat();
這是允許的:將調用第二個構造函數

默認構造函數

有一點非常重要,您應該知道並記住。

如果您的類沒有聲明一個構造函數,編譯器將添加一個默認構造函數,這是一個帶有 public 修飾符的無參數構造函數。

但是,如果您的類甚至聲明了一個構造函數,則不會添加默認構造函數,如果需要,您需要自己添加。

代碼 筆記
class Cat
{
   public String name;
   public int age;
}
Cat cat = new Cat();
這是允許的:將調用默認構造函數