JavaRush /จาวาบล็อก /Random-TH /ความรู้เบื้องต้นเกี่ยวกับชั้นเรียน: การเขียนคลาสของคุณเอง...

ความรู้เบื้องต้นเกี่ยวกับชั้นเรียน: การเขียนคลาสของคุณเอง ตัวสร้าง

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

    String name;
    int age;

}
สมมติว่าเรากำลังเขียนโปรแกรม และในโปรแกรมนี้เราต้องการแมวเพื่ออะไรบางอย่าง (เช่น เรามีคลินิกสัตวแพทย์ที่สามารถนัดหมายออนไลน์ได้) เราสร้างคลาส และระบุตัวแปรสองตัวสำหรับ คลาสCatนั้น - สตริงnameและตัวเลข ageตัวแปรคลาสดังกล่าวเรียกว่าฟิลด์ โดยพื้นฐานแล้ว นี่คือเทมเพลตสำหรับแมวทุกตัวที่เราจะสร้างในอนาคต cat แต่ละตัว (class object Cat) จะมีตัวแปรสองตัวคือ ชื่อ และ อายุ
public class Cat {

    String name;
    int age;

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

        System.out.println("We created a cat named" + barsik.name + ", his age - " + barsik.age);
    }

}
นั่นคือวิธีการทำงาน! เราสร้างแมว ตั้งชื่อและอายุให้กับมัน และส่งออกข้อมูลทั้งหมดไปยังคอนโซล ไม่มีอะไรซับซ้อน :) ชั้นเรียนส่วนใหญ่มักบรรยายถึงวัตถุและปรากฏการณ์ของโลกรอบตัว แมว โต๊ะ คน สายฟ้า หน้าหนังสือ วงล้อ - ทั้งหมดนี้จะถูกสร้างในโปรแกรมของคุณโดยใช้คลาสที่แยกจากกัน ตอนนี้เรามาดูตัวแปรที่เราสร้างในชั้นเรียนCatกัน สิ่งเหล่านี้เรียกว่าเขตข้อมูลหรือตัวแปรอินสแตนซ์ อันที่จริงชื่อเผยให้เห็นแก่นแท้ทั้งหมด แต่ละอินสแตนซ์Cat ( วัตถุ) ของคลาสจะมีตัวแปรเหล่านี้ แมวแต่ละตัวที่เราสร้างจะมีตัวแปรnameและตัวแปรของตัวageเอง โดยทั่วไปเป็นไปตามตรรกะ: สำหรับแมวจริง ๆ ทุกอย่างจะเหมือนกัน :) นอกจากตัวแปรอินสแตนซ์แล้วยังมีตัวแปรอื่น ๆ อีก - ตัวแปรคลาสหรือตัวแปรคงที่ เรามาเพิ่มตัวอย่างของเรา:
public class Cat {

    String name;
    int age;

    static int count = 0;

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

        Cat vasia = new Cat();
        vasia.age = 5;
        vasia.name = "Vasya";
        count++;

        System.out.println("We created a cat named" + barsik.name + ", his age - " + barsik.age);
        System.out.println("We created a cat named" + vasia.name + ", his age - " + vasia.age);

        System.out.println("Total number of cats = " + count);
    }
}
เอาต์พุตคอนโซล:

Мы создали кота по имени Барсик, его возраст - 3
Мы создали кота по имени Вася, его возраст - 5
Общее количество котов = 2
ตอนนี้เรามีตัวแปรใหม่ในคลาสของเรา - count(ปริมาณ) เธอมีหน้าที่รับผิดชอบในการนับแมวที่สร้างขึ้น แต่ละครั้งที่เราสร้าง cat ด้วยวิธีการหลัก เราจะเพิ่มตัวแปรนี้ขึ้น 1 ตัวแปรนี้ถูกกำหนดโดย คีย์เวิร์ด แบบคงที่ ซึ่งหมายความว่ามันเป็นของคลาสและไม่ใช่ของวัตถุเฉพาะของคลาส ซึ่งแน่นอนว่ามันสมเหตุสมผล หากแมวแต่ละตัวมีชื่อเป็นของตัวเอง เราก็ต้องมีตัวนับแมวหนึ่งตัวสำหรับทุกคน นี่คือสิ่งที่คำว่า staticช่วยให้คุณบรรลุผลได้ซึ่งcountเป็นตัวแปรเดียวกันสำหรับแมวทุกตัว โปรดทราบ: เมื่อเราพิมพ์ไปยังคอนโซล เราจะไม่เขียนbarsik.countหรือvasia.count. Catเธอไม่ได้เป็นของ Barsik หรือ Vasya แต่เธอเป็นของทั้งชั้นเรียน ดังนั้นจึงเป็นเรื่องcountง่าย คุณยังสามารถเขียนได้Cat.count- นั่นก็จะถูกต้องเช่นกัน nameสิ่งนี้จะไม่ทำงาน กับการส่งออกตัวแปรไปยังคอนโซล :
public class Cat {

    String name;
    int age;

    static int count = 0;

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

        System.out.println("We created a cat named" + name + ", his age - " + barsik.age);

        System.out.println("Total number of cats = " + count);
    }
}
ข้อผิดพลาด! nameแมวแต่ละตัวมีของตัวเอง นี่คือจุดที่คอมไพเลอร์สับสน "เอาชื่อออกไปที่คอนโซลเหรอ? ชื่อใคร? :/"

วิธีการ

นอกจากตัวแปรแล้ว แต่ละคลาสยังมีเมธอดอีกด้วย เราจะพูดถึงพวกเขาในการบรรยายแยกต่างหากโดยละเอียด แต่ประเด็นทั่วไปนั้นค่อนข้างง่าย เมธอดเป็นฟังก์ชันการทำงานของชั้นเรียนของคุณ วัตถุในคลาสนี้ทำอะไรได้บ้าง คุณคุ้นเคยกับวิธีใดวิธีหนึ่งอยู่แล้ว - นี่คือmain(). แต่ตามที่คุณจำได้ วิธีการนั้นmainเป็นแบบคงที่ นั่นคือ มันเป็นของทั้งคลาส (ตรรกะเหมือนกับตัวแปร) และวิธีการธรรมดาที่ไม่คงที่สามารถเรียกใช้ได้กับวัตถุเฉพาะที่เราสร้างขึ้นเท่านั้น ตัวอย่างเช่น หากเราต้องการเขียนคลาสสำหรับ cat เราต้องเข้าใจว่า cat ควรมีฟังก์ชันอะไรบ้างในโปรแกรมของเรา จากนี้ เราจะเขียนวิธีการสองสามวิธีดังนี้:
public class Cat {

    String name;
    int age;

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

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

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

        barsik.sayMeow();
        barsik.jump();

    }
}
ตอนนี้ชั้นเรียนของเราเหมือนกับคำอธิบายของแมวจริงๆ มากขึ้น! ตอนนี้เราไม่ได้มีแค่แมวชื่อบาร์ซิกที่มีชื่อและอายุเท่านั้น เขายังสามารถร้องเหมียวและกระโดดได้อีกด้วย! มันเป็นแมวแบบไหนที่ไม่มี "ฟังก์ชั่น" ดังกล่าว :) เราใช้วัตถุเฉพาะ - barsikและเรียกวิธีการของมันsayMeow()และjump(). เราดูที่คอนโซล:

Мяу!
Прыг-скок!
แมวตัวจริง! :)

การสร้างชั้นเรียนของคุณเอง นามธรรม

ในอนาคตคุณจะต้องเขียนชั้นเรียนของคุณเอง คุณควรใส่ใจอะไรเมื่อเขียน? หากเรากำลังพูดถึงตัวแปร คุณจะต้องใช้สิ่งที่เรียกว่า abstraction นามธรรมเป็นหนึ่งในสี่หลักการพื้นฐานของการเขียนโปรแกรมเชิงวัตถุ มันเกี่ยวข้องกับการเน้นคุณสมบัติหลักที่สำคัญที่สุดของวัตถุและในทางกลับกัน - ละทิ้งสิ่งรองที่ไม่มีนัยสำคัญ ตัวอย่างเช่น เรากำลังสร้างไฟล์ของพนักงานบริษัท Employeeในการสร้าง วัตถุพนักงาน เราได้เขียนคลาส ลักษณะใดที่สำคัญในการอธิบายพนักงานในไฟล์ของบริษัท ชื่อนามสกุล วันเกิด หมายเลขประกันสังคม หมายเลขประจำตัวผู้เสียภาษี แต่ไม่น่าเป็นไปได้ที่เราจะต้องมีส่วนสูง ดวงตา และสีผมของเขาในบัตรพนักงานของบริษัท บริษัทไม่ต้องการข้อมูลนี้ ดังนั้นสำหรับคลาสนี้Employeeเราจะตั้งค่าตัวแปรString name, int age, int socialInsuranceNumberและและint taxNumberเราจะละทิ้งข้อมูลที่ไม่จำเป็นสำหรับเรา (เช่น สีตา) และนามธรรมออกไป แต่ถ้าเราสร้างไฟล์ภาพนางแบบให้กับบริษัทโมเดลลิ่ง สถานการณ์จะเปลี่ยนไปอย่างมาก ในการอธิบายนางแบบแฟชั่น ความสูง สีตา และสีผมมีความสำคัญมากสำหรับเรา แต่หมายเลข TIN นั้นไม่สำคัญสำหรับเราเลย ดังนั้นในคลาสModelเราจึงต้องสร้างตัวแปรint height, String hair, String eyes. นี่คือวิธีการทำงานของนามธรรม มันง่ายมาก! :)

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

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

    String name;
    int age;

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

        System.out.println("Something has been happening in the program for 2 hours...");

        barsik.age = 3;
        barsik.name = "Barsik";

    }
}
ดูโค้ดนี้แล้วลองเดาว่ามีอะไรผิดปกติกับโปรแกรมของเรา เป็นเวลาสองชั่วโมงในโปรแกรมของเรา มีแมวตัวหนึ่งไม่มีชื่อหรืออายุ! แน่นอนว่านี่เป็นสิ่งที่ผิดอย่างสิ้นเชิง ไม่ควรมีแมวอยู่ในฐานข้อมูลของคลินิกสัตวแพทย์โดยไม่มีข้อมูลเกี่ยวกับแมว ตอนนี้เราปล่อยให้มันขึ้นอยู่กับโปรแกรมเมอร์ ถ้าเขาไม่ลืมระบุชื่อและอายุทุกอย่างจะเรียบร้อย หากเขาลืมจะมีข้อผิดพลาดในฐานข้อมูลแมวที่ไม่รู้จัก เราจะแก้ไขปัญหานี้ได้อย่างไร? มีความจำเป็นต้องห้ามการสร้างแมวโดยไม่มีชื่อและอายุ นี่คือจุดที่ ฟังก์ชั่นคอนสตรัคเตอร์เข้ามาช่วยเหลือเรา นี่คือตัวอย่าง:
public class Cat {

    String name;
    int age;

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

    public static void main(String[] args) {

        Cat barsik = new Cat("Barsik", 5);
    }
}
Constructor นั้นเป็นเทมเพลตสำหรับอ็อบเจ็กต์คลาส ในกรณีนี้ เราระบุว่าสำหรับแต่ละอ็อบเจ็กต์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 barsik = new Cat(); //error!
    }
}
ตอนนี้คลาสมี Constructor แล้ว คอมไพลเลอร์ Java จะรู้ว่าอ็อบเจ็กต์ควรมีลักษณะอย่างไร และจะไม่อนุญาตให้สร้างอ็อบเจ็กต์โดยไม่มีอาร์กิวเมนต์ที่ระบุไว้ในนั้น ตอนนี้เรามาดูคีย์เวิร์ดthisที่คุณเห็นภายใน Constructor ทุกอย่างก็ง่ายกับเขาเช่นกัน “นี่” ในภาษาอังกฤษ แปลว่า “นี่, นี้” นั่นคือคำนี้บ่งบอกถึงวัตถุเฉพาะ รหัสในตัวสร้าง
public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}
สามารถแปลได้เกือบตามตัวอักษร: " name for this cat (ซึ่งเรากำลังสร้าง) = อาร์กิวเมนต์ ชื่อที่ระบุในตัวสร้างอายุสำหรับแมวตัวนี้ (ซึ่งเรากำลังสร้าง) = อาร์กิวเมนต์ อายุที่ระบุในตัวสร้าง" หลังจากที่ Constructor เริ่มทำงาน คุณสามารถตรวจสอบว่า 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 barsik = new Cat("Barsik", 5);
        System.out.println(barsik.name);
        System.out.println(barsik.age);
    }
}
เอาต์พุตคอนโซล:

Барсик
5
เมื่อตัวสร้างเสร็จสิ้น:
Cat barsik = new Cat("Barsik", 5);
สิ่งต่อไปนี้เกิดขึ้นจริงภายใน:
this.name = "Barsik";
this.age = 5;
และวัตถุbarsik(มันคือthis) ได้รับการกำหนดค่าจากอาร์กิวเมนต์ของตัวสร้าง ที่จริงแล้ว หากคุณไม่ได้ระบุ Constructor ในคลาสมันจะยังคงสั่งให้ Constructor เริ่มทำงาน ! แต่สิ่งนี้เป็นไปได้อย่างไร? O_O ความจริงก็คือใน Java ทุกคลาสมีสิ่งที่เรียกว่าdefault Constructor ไม่มีข้อโต้แย้งใด ๆ แต่จะเริ่มทำงานทุกครั้งที่มีการสร้างวัตถุของคลาสใด ๆ
public class Cat {

    public static void main(String[] args) {

        Cat barsik = new Cat(); //this is where the default constructor worked
    }
}
เมื่อมองแวบแรกสิ่งนี้จะไม่สังเกตเห็นได้ชัดเจน เราสร้างวัตถุแล้วสร้างมันขึ้นมา งานของนักออกแบบอยู่ที่ไหน? หากต้องการดูสิ่งนี้ เรามาเขียนCatConstructor ว่างสำหรับคลาสด้วยมือของเราเอง และภายในนั้น เราจะส่งออกวลีบางส่วนไปยังคอนโซล หากแสดงขึ้น แสดงว่าคอนสตรัคเตอร์ทำงานแล้ว
public class Cat {

    public Cat() {
        System.out.println("Created a cat!");
    }

    public static void main(String[] args) {

        Cat barsik = new Cat(); //this is where the default constructor worked
    }
}
เอาต์พุตคอนโซล:

Создали кота!
นี่คือคำยืนยัน Constructor เริ่มต้นมักจะปรากฏอยู่ในคลาสของคุณอย่างมองไม่เห็นเสมอ แต่คุณจำเป็นต้องรู้คุณสมบัติอีกอย่างหนึ่งของมัน Constructor เริ่มต้นจะหายไปจากคลาสเมื่อคุณสร้าง Constructor บางตัวพร้อมอาร์กิวเมนต์ ข้อพิสูจน์นี้ในความเป็นจริงเราได้เห็นแล้วข้างต้น ที่นี่ในรหัสนี้:
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 barsik = new Cat(); //error!
    }
}
เราไม่สามารถสร้าง cat โดยไม่มีชื่อและอายุได้เนื่องจากเรากำหนด Constructor สำหรับCat: string + number ตัวสร้างเริ่มต้นหายไปจากคลาสทันทีหลังจากนี้ ดังนั้น อย่าลืมว่า: หากคุณต้องการ Constructor หลายตัวในคลาสของคุณ รวมถึง Constructor ว่างด้วยคุณต้องสร้างมันแยกกัน เช่น คลินิกสัตวแพทย์ของเราอยากทำความดีและช่วยเหลือแมวจรจัดที่เราไม่ทราบชื่อและอายุ จากนั้นโค้ดของเราควรมีลักษณะดังนี้:
public class Cat {

    String name;
    int age;

    //for domestic cats
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //for street cats
    public Cat() {
    }

    public static void main(String[] args) {

        Cat barsik = new Cat("Barsik", 5);
        Cat streetCat = new Cat();
    }
}
ตอนนี้เราได้ระบุ Constructor เริ่มต้นไว้อย่างชัดเจนแล้ว เราสามารถสร้าง cat ทั้งสองประเภทได้ ใน Constructor คุณสามารถกำหนดค่าได้อย่างชัดเจน ไม่ใช่แค่นำค่าเหล่านั้นมาจากอาร์กิวเมนต์เท่านั้น ตัวอย่างเช่น เราสามารถบันทึกแมวข้างถนนทุกตัวในฐานข้อมูลภายใต้ชื่อ "หมายเลขแมวข้างถนน...":
public class Cat {

    String name;
    int age;

    static int count = 0;

    public Cat() {
        count++;
        this.name = "Street cat number" + 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);
    }
}
เรามีตัวแปรcountที่เป็นตัวนับแมวข้างถนน แต่ละครั้งที่เราเรียกใช้ Constructor เริ่มต้น เราจะเพิ่มมันทีละ 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 barsik = new Cat("Barsik", 10); //error!
    }
}
ข้อผิดพลาด! Constructor อธิบายอย่างชัดเจนว่า: เมื่อสร้างอ็อบเจ็กต์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;
}
นี่คือนักออกแบบสองคนที่แตกต่างกันอย่างสิ้นเชิง! ตอนนี้แก้ไขปัญหาเล็กน้อยเพื่อรวมเนื้อหา :)
  • พิพิธภัณฑ์โบราณวัตถุ.
งานของคุณคือการออกแบบชั้นArtifactเรียน ศิลปวัตถุที่เก็บไว้ในพิพิธภัณฑ์มี 3 ประเภท เรื่องแรกเป็นเรื่องที่ไม่มีใครรู้นอกจากหมายเลขซีเรียลที่พิพิธภัณฑ์กำหนด (เช่น 212121) อย่างที่สองคือเกี่ยวกับหมายเลขซีเรียลและวัฒนธรรมที่ใช้สร้างขึ้น (เช่น 212121, "แอซเท็ก") ประเภทที่สามเกี่ยวกับหมายเลขซีเรียลที่ทราบ วัฒนธรรมที่ใช้สร้างมัน และอายุที่แน่นอนของการสร้าง (เช่น 212121, “Aztecs”, 12) สร้างชั้นเรียนArtifactที่อธิบายโบราณวัตถุที่เก็บไว้ในพิพิธภัณฑ์ และเขียนตัวสร้างตามจำนวนที่ต้องการ ในเมธอดmain()ให้สร้างหนึ่งส่วนของแต่ละประเภท
public class Artifact {

    public static void main(String[] args) {
    }
}
  • เว็บไซต์การประชุม
คุณกำลังสร้างฐานข้อมูลผู้ใช้สำหรับเว็บไซต์หาคู่ แต่ปัญหาคือคุณลืมว่าต้องระบุลำดับใด และคุณไม่มีข้อกำหนดทางเทคนิคอยู่ในมือ ออกแบบคลาสUserที่จะมีฟิลด์ - ชื่อ ( String) อายุ ( short) และส่วนสูง ( int) สร้างจำนวนตัวสร้างที่ต้องการเพื่อให้สามารถระบุชื่อ อายุ และส่วนสูงในลำดับใดก็ได้
public class User {

    String name;
    short age;
    int height;

    public static void main(String[] args) {

    }
}
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION