CodeGym /จาวาบล็อก /สุ่ม /Java Classes: การเขียนคลาสของคุณเอง ตัวสร้าง
John Squirrels
ระดับ
San Francisco

Java Classes: การเขียนคลาสของคุณเอง ตัวสร้าง

เผยแพร่ในกลุ่ม
สวัสดี! วันนี้เราจะพูดถึงคลาสในภาษาจาวา คุณสามารถพูดได้ว่าคลาสเป็นรากฐานที่สำคัญของการเขียนโปรแกรม Java เมื่อคุณเป็นโปรแกรมเมอร์ งานเกือบทั้งหมดของคุณจะเป็นการเขียนคลาสของคุณเองซึ่งมีฟังก์ชันต่างๆ มาดูกันว่ามันหมายถึงอะไรและทำงานอย่างไร :) ดังที่คุณทราบ Java เป็นภาษาโปรแกรมเชิงวัตถุ โปรแกรมทั้งหมดประกอบด้วยวัตถุที่เกี่ยวข้องกันไม่ทางใดก็ทางหนึ่ง โดยพื้นฐานแล้วคลาสคือเทมเพลตสำหรับวัตถุ กำหนดว่าวัตถุจะมีลักษณะอย่างไรและมีหน้าที่อะไรบ้าง วัตถุทุกชิ้นเป็นวัตถุของบางคลาส พิจารณาตัวอย่างง่ายๆ นี้:

public class Cat {

    String name;
    int age;

}
สมมติว่าเรากำลังเขียนโปรแกรมที่เกี่ยวข้องกับแมวด้วยเหตุผลบางประการ (เช่น เรามีคลินิกรักษาสัตว์ที่ให้บริการเข้าถึงบัญชีออนไลน์) เราได้สร้าง คลาส Catและประกาศตัวแปรสองตัวในนั้น: ชื่อสตริงและint 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 เราสร้างแมวชื่อปุย อายุของเขาคือ 5 จำนวนแมวทั้งหมด = 2 ตอนนี้ชั้นเรียนของเรามีตัวแปรใหม่ที่เรียกว่าการนับ มีหน้าที่นับแมวที่สร้างขึ้น ทุกครั้งที่เราสร้างแมวในหลักวิธีการ เราเพิ่มตัวแปรนี้ 1 ตัวแปรนี้ถูกประกาศโดยใช้คำหลักคงที่ ซึ่งหมายความว่าเป็นของคลาส ไม่ใช่ของเฉพาะของคลาส ซึ่งแน่นอนว่าสมเหตุสมผล: ชื่อของแมวแต่ละตัวเป็นของแมวตัวนั้น แต่เราต้องการตัวนับแมวหนึ่งตัวที่ใช้กับพวกมันทั้งหมด นี่คือสิ่งที่คำหลักคงที่ทำให้สำเร็จ: มันทำให้ตัวแปรนับเป็นตัวแปรเดียวสำหรับแมวทั้งหมด หมายเหตุ: เมื่อเราแสดงตัวแปร เราจะไม่ใช้ smudge.count หรือ fluffy.count ไม่ได้เป็นของ Smudge หรือ Fluffy; มันเป็นของคลาสCat ทั้งหมด นั่นเป็นเหตุผลที่มันเป็นเพียงการนับ คุณยังสามารถเขียน Cat.count นั่นก็จะถูกด้วย เมื่อแสดงชื่อตัวแปร เราจะไม่ทำสิ่งต่อไปนี้:

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() แต่อย่างที่คุณจำได้ เมธอดหลักเป็นแบบสแตติก ซึ่งหมายความว่าเป็นของทั้งคลาส (ลอจิกเหมือนกับตัวแปร) อย่างไรก็ตาม เมธอดมาตรฐานที่ไม่คงที่สามารถเรียกได้บนวัตถุเฉพาะที่เราสร้างขึ้นเท่านั้น เช่น ถ้าเราต้องการจะเขียนคลาส cat เราต้องรู้ว่า cat ในโปรแกรมของเราควรมีหน้าที่อะไร ในสมมติฐานนั้น ลองเขียนวิธีการสองสามวิธีสำหรับแมวของเรา:

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) เขายังสามารถพูดว่า meow และกระโดด! จะเป็นแมวแบบไหนถ้าไม่มี "ฟังก์ชัน" นั้น :) เรากำลังนำวัตถุเฉพาะ (รอยเปื้อน) และเรียกมันว่าเมธอดsayMeow()และjump() ลองดูที่คอนโซล: Meow! โผน! แมวตัวจริง! :)

การสร้างชั้นเรียนของคุณเอง สิ่งที่เป็นนามธรรม

ในอนาคตคุณจะต้องเขียนชั้นเรียนของคุณเอง สิ่งที่คุณต้องระวังเมื่อคุณเขียน? หากเรากำลังพูดถึงตัวแปร คุณจะต้องใช้สิ่งที่เรียกว่านามธรรม Abstraction เป็นหนึ่งในสี่หลักการพื้นฐานของการเขียนโปรแกรมเชิงวัตถุ หมายถึงการแยกคุณลักษณะที่สำคัญและสำคัญที่สุดของรายการ และในทางกลับกัน การละทิ้งคุณลักษณะที่เล็กน้อยหรือไม่มีนัยสำคัญ เช่น สร้างตู้เก็บเอกสารสำหรับพนักงานบริษัท ในการสร้างวัตถุพนักงาน เราได้เขียนพนักงานระดับ. ลักษณะใดที่เป็นตัวบ่งชี้ที่สำคัญของพนักงานสำหรับตู้เก็บเอกสารของบริษัทของเรา ชื่อ วันเกิด SSN และ ID พนักงาน แต่ไม่น่าเป็นไปได้ที่เราจะต้องการส่วนสูง สีตา หรือสีผมของพนักงานสำหรับบันทึกข้อมูลพนักงานของบริษัท บริษัทไม่ต้องการข้อมูลนี้ ดังนั้น ใน คลาส Employeeเราประกาศตัวแปรต่อไปนี้: String name , int age , int socialSecurityNumber , and int EmployeeId. และเราตัดข้อมูลที่ไม่จำเป็นออกไป (เช่น สีตา) กล่าวอีกนัยหนึ่ง เราสร้างสิ่งที่เป็นนามธรรม อย่างไรก็ตาม หากเรากำลังสร้างตู้เก็บเอกสารสำหรับเอเจนซี่โมเดล สถานการณ์จะเปลี่ยนไปอย่างมาก ความสูงของนางแบบ สีตา และสีผมเป็นคุณลักษณะที่สำคัญ แต่ SSN ของเธอไม่เกี่ยวข้องกับเราเลย ดังนั้นใน คลาส Modelเราต้องสร้างตัวแปรต่อไปนี้: ความสูงของสตริง , ขนของสตริง , ตาของสตริง นั่นเป็นวิธีที่นามธรรมทำงาน—ง่ายนิดเดียว! :)

คอนสตรัคเตอร์

กลับไปที่ตัวอย่างแมวของเรา

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);
    }
}
โดยพื้นฐานแล้ว ตัวสร้างคือเทมเพลตสำหรับออบเจกต์ของคลาส ในกรณีนี้ เราระบุว่า ต้องระบุอาร์กิวเมนต์ 2 รายการ คือStringและint สำหรับแต่ละ อ็อบเจกต์cat ถ้าเราพยายามสร้างแมวนิรนามตอนนี้ มันจะไม่ทำงาน

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 ที่คุณเห็นในตัวสร้าง มันง่ายเกินไป คำหลักนี้ใช้สำหรับระบุวัตถุเฉพาะ รหัสในตัวสร้าง

public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}
สามารถตีความได้เกือบทุกคำ: "ชื่อของแมวตัวนี้ (ตัวที่เรากำลังสร้าง) = อาร์กิวเมนต์ที่ส่งผ่านสำหรับพารามิเตอร์ชื่อคอนสตรัคเตอร์ อายุของแมวตัวนี้ (ตัวที่เรากำลังสร้าง) = อาร์กิวเมนต์ที่ส่งผ่านสำหรับตัวสร้าง พารามิเตอร์อายุ" หลังจากคอนสตรัคเตอร์ทำงาน คุณสามารถตรวจสอบได้ว่าค่าที่จำเป็นทั้งหมดถูกกำหนดให้กับ cat ของเราแล้ว:

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;
และค่าของอาร์กิวเมนต์ที่ส่งไปยังคอนสตรัคเตอร์ถูกกำหนดให้กับ วัตถุ รอยเปื้อน (นั่นคือสิ่งที่อ้างถึงในกรณีนี้) ในความเป็นจริง แม้ว่าคุณจะไม่ได้ประกาศตัวสร้างใด ๆ ในคลาส มันก็ยังเรียกตัวสร้างอยู่ดี! แต่เป็นไปได้อย่างไร? О_О เนื่องจากคลาส 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 ได้หากไม่มีชื่อและอายุ เนื่องจากเราประกาศ ตัวสร้าง Catด้วยพารามิเตอร์ string และ int สิ่งนี้ทำให้ตัวสร้างเริ่มต้นหายไปจากคลาสทันที ดังนั้นอย่าลืมว่าหากคุณต้องการตัวสร้างหลายตัวในชั้นเรียนของคุณ รวมถึงตัวสร้างที่ไม่มีข้อโต้แย้ง คุณจะต้องประกาศแยกต่างหาก คลินิกของเราต้องการทำความดีและช่วยเหลือลูกแมวจรจัดที่ไม่ทราบชื่อและอายุ จากนั้นรหัสของเราควรมีลักษณะดังนี้:

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();
    }
}
ตอนนี้เราได้ระบุตัวสร้างเริ่มต้นที่ชัดเจนแล้ว เราสามารถสร้างแมวทั้งสองประเภทได้ ในตัวสร้าง คุณสามารถกำหนดค่าได้โดยตรง คุณไม่จำเป็นต้องนำมาจากข้อโต้แย้งเสมอไป ตัวอย่างเช่น เราสามารถติดป้ายกำกับแมวข้างถนนทั้งหมดในฐานข้อมูลโดยใช้ "แมวข้างถนนหมายเลข <จำนวน>" เป็นเทมเพลต :

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 และแนบหมายเลขนี้กับชื่อแมว ลำดับของอาร์กิวเมนต์มีความสำคัญมากสำหรับคอนสตรัคเตอร์ เรามาสลับอาร์กิวเมนต์ชื่อและอายุที่ส่งไปยังตัวสร้างของเรา

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. พิพิธภัณฑ์โบราณวัตถุ.

    งานของคุณคือการออกแบบคลาสสิ่งประดิษฐ์
    มีโบราณวัตถุสามประเภทที่เก็บไว้ที่พิพิธภัณฑ์
    เราไม่รู้อะไรเลยเกี่ยวกับประเภทแรก ยกเว้นหมายเลขซีเรียลที่พิพิธภัณฑ์กำหนดให้ (เช่น 212121)
    สำหรับประเภทที่สอง เราทราบหมายเลขซีเรียลและวัฒนธรรมที่สร้างหมายเลขดังกล่าว (เช่น: 212121, "แอซเท็ก")
    สำหรับประเภทที่สาม เรารู้หมายเลขซีเรียล วัฒนธรรมที่สร้าง และศตวรรษที่มันถูกสร้างขึ้น (เช่น: 212121, "แอซเท็ก", 12)

    สร้าง คลาส สิ่งประดิษฐ์ที่อธิบายโบราณวัตถุที่เก็บไว้ที่พิพิธภัณฑ์ และเขียนชุดตัวสร้างที่จำเป็นสำหรับชั้นเรียน จากนั้นใน เมธอด 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