CodeGym /Java Blog /Toto sisi /Java 類:編寫自己的類、構造函數
John Squirrels
等級 41
San Francisco

Java 類:編寫自己的類、構造函數

在 Toto sisi 群組發布
你好!今天我們將討論Java中的類。您可以說類構成了 Java 編程的基石。當你成為一名程序員時,幾乎你的全部工作就是編寫你自己的具有各種功能的類。讓我們看看這意味著什麼以及它是如何工作的。:) 如您所知,Java 是一種面向對象的編程語言。所有程序都由以某種方式相互關聯的對象組成。類本質上是對象的模板。它決定了對象的外觀和功能。每個對像都是某個類的對象。考慮這個非常簡單的例子:

public class Cat {

    String name;
    int age;

}
假設我們出於某種原因正在編寫一個涉及貓的程序(例如,我們有一家獸醫診所提供在線帳戶訪問權限)。我們創建了一個Cat類,並在其中聲明了兩個變量:String nameint age。這些成員變量稱為字段。從本質上講,這是我們將來要創建的所有貓的模板。每個Cat對像都有兩個變量:名稱和年齡。

public class Cat {

    String name;
    int age;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";

        System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
    }

}
這是它的工作原理!我們創建了一隻貓,給它起名字和年齡,然後將其全部顯示在控制台上。小菜一碟。:) 通常,類描述現實世界中的事物和現象。一隻貓、一張桌子、一個人、一道閃電、一本書的一頁、一個輪子——您將使用單獨的類在您的程序中創建所有這些東西。現在,讓我們關注我們在Cat類中聲明的變量。它們被稱為字段或實例變量。他們的名字真的說明了一切。Cat類的每個實例(或對象)都將具有這些變量。我們創建的每隻貓都有自己的名字變量和年齡多變的。這是有道理的——真正的貓基本上就是這樣。:) 除了實例變量,還有類變量(靜態變量)。讓我們完成我們的例子:

public class Cat {

    String name;
    int age;

    static int count = 0;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";
        count++;

        Cat fluffy = new Cat();
        fluffy.age = 5;
        fluffy.name = "Fluffy";
        count++;

        System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
        System.out.println("We created a cat named " + fluffy.name + ". His age is " + fluffy.age);

        System.out.println("Total number of cats = " + count);
    }
}
控制台輸出:我們創建了一隻名為 Smudge 的貓。他的年齡是 3 我們創造了一隻名叫 Fluffy 的貓。他的年齡是 5 貓的總數 = 2 現在我們班有一個新變量叫做 count。它負責計算創建的貓。每次我們在main中創建一隻貓方法,我們將這個變量增加 1。這個變量是使用關鍵字 static 聲明的。這意味著它屬於類,而不屬於類的特定對象。這當然是有道理的:每隻貓的名字都屬於那隻特定的貓,但我們需要一個適用於所有貓的貓計數器。這正是關鍵字 static 所完成的:它使 count 變量成為所有貓的單個變量。注意:當我們顯示變量時,我們沒有使用 smudge.count 或 fluffy.count。它既不屬於 Smudge 也不屬於 Fluffy;它屬於整個Cat類。這就是為什麼它只是計數。您也可以編寫 Cat.count。那也是正確的。當顯示 name 變量時,我們不會執行以下操作:

public class Cat {

    String name;
    int age;

    static int count = 0;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";
        count++;

        System.out.println("We created a cat named " + name + ". His age is " + smudge.age);

        System.out.println("Total number of cats = " + count);
    }
}
這是一個錯誤!每隻貓都有自己的名字。編譯器在這裡感到困惑。“向控制台輸出一個名字?誰的名字?” :/“

方法

除了變量,每個類都有方法。我們將在單獨的課程中更詳細地討論它們,但一般原則非常簡單。方法定義了類的功能,即類的對象可以做什麼。您已經熟悉其中一種方法:main()方法。但是,您可能還記得,main方法是靜態的,這意味著它屬於整個類(邏輯與變量相同)。但是,標準的非靜態方法只能在我們創建的特定對像上調用。比如我們要寫一個貓類,我們需要知道我們程序中的一隻貓應該具備哪些功能。在此前提下,讓我們為我們的貓寫幾個方法:

public class Cat {

    String name;
    int age;

    public void sayMeow() {
        System.out.println("Meow!");
    }

    public void jump() {
        System.out.println("Pounce!");
    }

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";

        smudge.sayMeow();
        smudge.jump();

    }
}
一探究竟!現在我們班更像一隻貓了!現在我們不只有一隻有名字(“Smudge”)和年齡(3)的貓。他還會喵喵叫和跳躍!如果沒有這種“功能”,它會是什麼樣的貓?:) 我們正在獲取一個特定的對象(塗抹)並調用它的sayMeow()jump()方法。再看控制台:喵!猛撲!一隻真正的貓!:)

創建自己的課程。抽象

將來,您將不得不編寫自己的類。寫的時候需要注意什麼?如果我們談論的是變量,那麼您將需要使用一種稱為抽象的東西。抽像是面向對象程序設計的四大基本原則之一。這意味著提取項目最重要和最重要的特徵,相反,拋棄那些次要或無關緊要的特徵。例如,讓我們為公司員工創建一個文件櫃。為了創建員工對象,我們編寫了一個Employee班級。哪些特徵是我們公司文件櫃員工的重要描述符?姓名、出生日期、SSN 和員工 ID。但是我們不太可能需要員工的身高、眼睛顏色或頭髮顏色來作為公司的員工記錄。公司不需要這些信息。因此,在Employee類中,我們聲明了以下變量:String nameint ageint socialSecurityNumberint employeeId. 而且我們遺漏了不必要的信息(如眼睛顏色)。換句話說,我們創建了一個抽象。但是,如果我們為模特經紀公司製作文件櫃,情況就會發生巨大變化。模特的身高、眼睛顏色和頭髮顏色是重要的特徵,但她的 SSN 與我們絕對無關。因此,在Model類中,我們需要創建以下變量:String heightString hairString eyes。這就是抽象的工作原理——很簡單!:)

構造器

讓我們回到貓的例子。

public class Cat {

    String name;
    int age;

    public static void main(String[] args) {
        Cat smudge = new Cat();

        System.out.println("Here the program does something for 2 hours...");

        smudge.age = 3;
        smudge.name = "Smudge";

    }
}
查看這段代碼並嘗試找出我們的程序出了什麼問題。我們的節目有一隻沒有名字或年齡的貓 2 小時!當然,這本質上是錯誤的。獸醫診所的數據庫不應包括沒有信息的貓。目前,我們的貓任由程序員擺佈。我們相信他不會忘記指定姓名和年齡,一切都會好起來的。如果他忘記了,數據庫就會出問題:未命名的貓。我們如何解決這個問題?我們必須以某種方式防止沒有名字和年齡的貓被創造出來。這是構造函數來救援的地方。讓我們舉個例子:

public class Cat {

    String name;
    int age;

    // Constructor for the Cat class
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 5);
    }
}
本質上,構造函數是類對象的模板。在這種情況下,我們指出必須為每個cat對象指定兩個參數,一個String和一個int。如果我們現在嘗試創建一隻無名貓,那是行不通的。

public class Cat {

    String name;
    int age;

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

    public static void main(String[] args) {

        Cat smudge = new Cat(); // Error!
    }
}
現在類有了構造函數,Java 編譯器就知道對象應該是什麼樣子,並且不允許在不指定參數的情況下創建對象。現在,讓我們研究一下您在構造函數中看到的關鍵字 this。這也很簡單。關鍵字 this 用於指示特定對象。構造函數中的代碼

public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}
幾乎可以一字不差地解釋:“這隻貓的名字(我們正在創建的)= 為構造函數的名稱參數傳入的參數。這隻貓的年齡(我們正在創建的)= 為構造函數的參數傳入的參數年齡參數。” 構造函數運行後,您可以驗證是否已將所有必要的值分配給我們的貓:

public class Cat {

    String name;
    int age;

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

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 5);
        System.out.println(smudge.name);
        System.out.println(smudge.age);
    }
}
控制台輸出:Smudge 5 調用構造函數時:

Cat smudge = new Cat("Smudge", 5);
這是內部實際發生的事情:

this.name = "Smudge";
this.age = 5;
傳遞給構造函數的參數值被分配給smudge對象(這就是本例中 this 所指的)。事實上,即使你不在類中聲明任何構造函數,它仍然會調用構造函數!但這怎麼可能呢?О_О 因為,所有的 Java 類都有一個所謂的默認構造函數。它不接受任何參數,但每次您創建任何類的任何對象時都會調用它。

public class Cat {

    public static void main(String[] args) {

        Cat smudge = new Cat(); // The default constructor is invoked here
    }
}
乍一看,這可能並不明顯。我們創建了一個對象,那又如何呢?構造函數在這裡做什麼?為了看到它,讓我們顯式地為Cat類編寫一個空的構造函數。在其中,我們將向控制台輸出一些短語。如果顯示該短語,則調用了構造函數。

public class Cat {

    public Cat() {
        System.out.println("A cat has been created!");
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // The default constructor is invoked here
    }
}
控制台輸出:已創建一隻貓!有確認。默認構造函數總是不可見地存在於您的類中。但是你還需要知道一件事。一旦創建帶參數的構造函數,默認構造函數就會從類中刪除。事實上,我們已經在上面看到了這方面的證據。它在這段代碼中:

public class Cat {

    String name;
    int age;

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

    public static void main(String[] args) {

        Cat smudge = new Cat(); // Error!
    }
}
我們不能創建沒有名字和年齡的貓,因為我們聲明了一個帶有字符串和整數參數的Cat構造函數。這導致默認構造函數立即從類中消失。所以一定要記住,如果你的類中需要多個構造函數,包括一個無參構造函數,你必須單獨聲明它。我們診所希望做好事,幫助那些名字和年齡不詳的無家可歸的小貓。那麼我們的代碼應該是這樣的:

public class Cat {

    String name;
    int age;

    // For cats with owners
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // For street cats
    public Cat() {
    }

    public static void main(String[] args) {
        
        Cat smudge = new Cat("Smudge", 5);
        Cat streetCat = new Cat();
    }
}
現在我們已經指定了一個顯式默認構造函數,我們可以創建兩種類型的貓。 在構造函數中,可以直接賦值。你不必總是從爭論中提取它們。例如,我們可以使用“流浪貓編號 <count>”作為模板來標記數據庫中的所有流浪貓。:

public class Cat {

    String name;
    int age;

    static int count = 0;

    public Cat() {
        count++;
        this.name = "Street cat No. " + count;
    }

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

    public static void main(String[] args) {

        Cat streetCat1 = new Cat();
        Cat streetCat2 = new Cat();
        System.out.println(streetCat1.name);
        System.out.println(streetCat2.name);
    }
}
我們有一個計數變量,它計算我們的流浪貓。每次執行默認構造函數時,我們都會將計數加 1 並將此數字附加到貓的名字上。參數的順序對於構造函數來說非常重要。讓我們交換傳遞給構造函數的 name 和 age 參數。

public class Cat {

    String name;
    int age;

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

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 10); // Error!
    }
}
我們得到一個錯誤!構造函數明確規定,創建Cat對象時,必須依次傳遞一個數字和一個字符串。所以,我們的代碼不起作用。在聲明自己的類時一定要記住並遵守這條規則:

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

public Cat(int age, String name) {
    this.age = age;
    this.name = name;
}
這是兩個完全不同的構造函數!現在,完成幾項任務以鞏固您對材料的理解。:)
  1. 古物博物館。

    您的任務是設計一個Artifact類。
    博物館保存了三種類型的文物。
    除了博物館分配的序列號(例如:212121)外,我們對第一種一無所知。
    對於第二種類型,我們知道序列號和創建它的文化(例如:212121,“Aztecs”)。
    對於第三種類型,我們知道序列號、創建它的文化以及創建它的世紀(例如:212121,“Aztecs”,12)。

    創建一個Artifact類來描述保存在博物館中的古物,並為該類編寫所需的一組構造函數。然後,在main()方法中,為每種類型創建一個工件。

    
    public class Artifact {
        
        // Write your code here
    
        public static void main(String[] args) {
            // Write your code here
        }
    }
    
  2. 約會網站

    讓我們為約會網站創建一個用戶數據庫。
    但問題是:您忘記了所需的參數順序,而且沒有可用的技術文檔。
    設計一個User類,它將具有以下字段:姓名 ( String )、年齡 ( short ) 和身高 ( int )。
    創建適當數量的構造函數,以便可以按任意順序指定姓名、年齡和身高。

    
    public class User {
    
        String name;
        short age;
        int height;
    
        // Write your code here
    
        public static void main(String[] args) {
            
        }
    }
    
為了鞏固您所學的知識,我們建議您觀看我們的 Java 課程中的視頻課程
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION