1. มรดก

ในการทำงานกับเอ็น จิ้นเกม CodeGym คุณจะต้องใช้การสืบทอด แต่ถ้าคุณไม่รู้ว่ามันคืออะไร? ในแง่หนึ่งคุณต้องเข้าใจและศึกษาหัวข้อนี้ ในทางกลับกัน เครื่องยนต์ได้รับการออกแบบมาเป็นพิเศษให้เรียบง่ายมาก ดังนั้นคุณจึงสามารถเรียนรู้เกี่ยวกับมรดกเพียงผิวเผินได้

ดังนั้นมรดกคืออะไร? พูดง่ายๆ ว่ามรดกคือความสัมพันธ์ระหว่างสองคลาส หนึ่งในนั้นทำหน้าที่เป็นคลาสผู้ปกครอง และอีกอันหนึ่งจะกลายเป็นคลาสย่อย (ลูกหลาน) ยิ่งไปกว่านั้น คลาสผู้ปกครองอาจไม่รู้ด้วยซ้ำว่ามีคลาสรองลงมา กล่าวอีกนัยหนึ่ง ผู้ปกครองไม่ได้รับประโยชน์มากนักจากการมีคลาสลูกหลาน

แต่การสืบทอดให้ประโยชน์มากมายแก่ชนชั้นลูก สิ่งที่สำคัญที่สุดคือตัวแปรและวิธีการทั้งหมดของคลาสพาเรนต์ปรากฏในคลาสย่อยราวกับว่ารหัสของคลาสพาเรนต์ถูกคัดลอกไปยังคลาสย่อยโดยตรง สิ่งนี้ไม่ถูกต้องทั้งหมด แต่เพียงพอสำหรับความเข้าใจพื้นฐานเกี่ยวกับมรดก

ต่อไปนี้เป็นตัวอย่างที่จะช่วยให้คุณเข้าใจการสืบทอดได้ดีขึ้น

ตัวอย่างที่ 1 — นี่คือตัวอย่างที่ง่ายที่สุด

public class Parent
{
}
คลาสChildสืบทอดParentคลาสด้วยความช่วยเหลือของextendsคำหลัก
public class Child extends Parent
{
}

ตัวอย่างที่ 2 — การใช้ตัวแปรของคลาสพาเรนต์

public class Parent
{
  public int age;
  public String name;
}
คลาสChildสามารถใช้ฟิลด์ageและnameของคลาสParentได้เหมือนกับว่ามีการประกาศในChildคลาสนั้น
public class Child extends Parent
{
  public void printInfo()
  {
    System.out.println(name + " " + age);
  }
}

ตัวอย่างที่ 3 — ใช้ method ของ parent class

public class Parent
{
   public int age;
   public String name;
   public getName() {
      return name;
   }
}
คลาสChildสามารถใช้ตัวแปรและเมธอดของคลาส Parent ได้เหมือนประกาศในChildคลาส ในตัวอย่างนี้ เราใช้getName()วิธี
public class Child extends Parent
{
   public void printInfo()
   {
      System.out.println(getName() + " " + age);
   }
}

เราสามารถพูดได้ว่าจากมุมมองของคอมไพเลอร์ Java เราเพียงแต่คัดลอกโค้ดของคลาสพาเรนต์ลงในโค้ดของคลาสย่อย:

public class Child extends Parent
{
   public int age;        // An inherited variable
   public String name;    // An inherited variable
   public getName() {     // An inherited method
      return name;
   }

   public void printInfo()
   {
      System.out.println(getName() + " " + age);
   }
}
นี่คือลักษณะChildของคลาสจากมุมมองของคอมไพเลอร์


2. วิธีการเอาชนะ

บางครั้งมีสถานการณ์ที่เราทำให้ChildคลาสของเราสืบทอดParentคลาสที่มีประโยชน์มาก ทำให้ลูกสืบทอดตัวแปรและเมธอดทั้งหมดของพาเรนต์ แต่วิธีการเหล่านั้นบางวิธีอาจไม่ได้ผลตามที่เราต้องการหรือไม่ได้ผลตามที่เราต้องการ

คุณจะทำอย่างไรในกรณีนี้? เราสามารถลบล้างวิธีการที่เราไม่ชอบการใช้งาน นี่เป็นสิ่งง่ายๆ ที่ต้องทำ: ในChildคลาสของเรา เราเพียงแค่ประกาศเมธอดที่มีลายเซ็นเดียวกับเมธอดในParentคลาส จากนั้นเขียนโค้ดของเราเองลงไป

ตัวอย่างที่ 1 — การแทนที่เมธอด

public class Parent
{
   public String name;
   public void setName(String nameNew) {
      name = nameNew;
   }

   public getName() {
      return name;
   }
}
วิธีprintInfo()การจะแสดงวลีต่อไปนี้:
Luke, No!!!
public class Child extends Parent
{
   public void setName(String nameNew) {
      name = nameNew + ", No!!!";
   }

   public void printInfo()
   {
      setName("Luke");
      System.out.println(getName());
   }
}

ทำให้สถานการณ์ง่ายขึ้นเล็กน้อย การสืบทอดทำให้รหัสของคลาสพาเรนต์ถูกคัดลอกไปยังคลาสย่อย แต่ถ้าคลาสลูกหลานเป็นเมธอดที่มีอยู่ในคลาสบรรพบุรุษอยู่แล้ว เมธอดนั้นจะไม่คัดลอกมาจากคลาสบรรพบุรุษ ที่นี่เราบอกว่าเมธอดในคลาสลูกจะแทนที่เมธอดในคลาสพาเรนต์ ดูตัวอย่างด้านล่าง บางทีมันอาจจะช่วยให้ชัดเจนขึ้นเล็กน้อย:

นี่คือลักษณะที่คลาสลูกปรากฏขึ้นจากมุมมองของคอมไพเลอร์:
public class Child extends Parent
{
   public String name;    // An inherited variable

   public void setName(String nameNew)  // The overridden method replaces the inherited one
   {
      name = nameNew + ", No!!!";
   }

   public getName()    // An inherited method
   {
      return name;
   }

   public void printInfo()
   {
      setName("Luke");
      System.out.println(getName());
   }
}

ตัวอย่างที่ 2 - เวทมนตร์มรดกเล็กน้อย (และวิธีการเอาชนะ)

public class Parent
{
   public getName() {
      return "Luke";
   }

   public void printInfo()
   {
      System.out.println( getName() );
   }
}
public class Child extends Parent
{
   public getName() {
      return "Luke, I am your father";
   }
}

ถ้าprintInfo()เมธอดถูกเรียกใช้ในParentประเภท มันจะเรียกgetName()เมธอดของParentคลาส

หากมีprintInfo()การเรียกใช้เมธอดบนChildอ็อบเจกต์ ก็จะเรียกgetName()เมธอดของChildคลาส

กล่าวอีกนัยหนึ่งprintInfo()เมธอดถูกประกาศในParentคลาสเท่านั้น แต่จะเรียกgetName()เมธอดของChildคลาสถ้าprintInfo()เมธอดนั้นถูกเรียกบนChildวัตถุ

ตัวอย่าง:

Parent parent = new Parent();
parent.printnInfo();
รหัสนี้แสดงข้อความต่อไปนี้บนหน้าจอ:
Luke
Child child = new Child();
child.printnInfo();
รหัสนี้แสดงข้อความต่อไปนี้บนหน้าจอ:
Luke, I am your father

และทั้งหมดเป็นเพราะจากมุมมองของคอมไพเลอร์ (เป็นเวอร์ชันที่เรียบง่ายมาก) โค้ดของChildคลาสมีลักษณะดังนี้:

public class Child extends Parent
{
   public getName() {
      return "Luke, I am your father";
   }

   public void printInfo()
   {
      System.out.println(getName());
   }
}
นี่คือลักษณะChildของคลาสจากมุมมองของคอมไพเลอร์


3. รายการ

ต่อไปนี้เป็นการแจ้งเตือนสั้นๆ เกี่ยวกับรายการ ( List) รายการมีหลายอย่างเหมือนกันกับอาร์เรย์:

  • พวกเขาสามารถเก็บข้อมูลจำนวนมากในประเภทเฉพาะ
  • พวกเขาให้คุณรับองค์ประกอบตามดัชนี
  • ดัชนีขององค์ประกอบเริ่มต้น0ที่

ข้อดีของรายการ:

ซึ่งแตกต่างจากอาร์เรย์ รายการสามารถเปลี่ยนขนาดไดนามิกได้ ทันทีหลังจากสร้าง ขนาดของรายการ0คือ เมื่อมีการเพิ่มรายการลงในรายการ ขนาดจะเพิ่มขึ้น ตัวอย่างการสร้างรายการ:

ArrayList<String> myList = new ArrayList<String>();
การสร้างใหม่ArrayList

ค่าที่ระบุในวงเล็บมุมคือประเภทข้อมูลที่รายการสามารถจัดเก็บได้

ต่อไปนี้เป็นวิธีการบางอย่างสำหรับการทำงานกับรายการ:

รหัส คำอธิบายสั้น ๆ
ArrayList<String> list = new ArrayList<String>();
สร้างรายการสตริงใหม่
list.add("name");
เพิ่มองค์ประกอบที่ส่วนท้ายของรายการ
list.add(0, "name");
เพิ่มองค์ประกอบไปที่จุดเริ่มต้นของรายการ
String name = list.get(5);
รับองค์ประกอบตามดัชนี
list.set(5, "new name");
เปลี่ยนองค์ประกอบตามดัชนี
int count = list.size();
รับจำนวนองค์ประกอบในรายการ
list.remove(4);
ลบองค์ประกอบออกจากรายการ

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับรายการ คุณสามารถอ่านบทความต่อไปนี้:



4. ตัวเลขสุ่ม

เอ็นจิ้นเกม CodeGym มีสองวิธีที่สามารถใช้เพื่อสร้างตัวเลขสุ่ม วิธีการเหล่านี้คือ:

int getRandomNumber(int max)
int getRandomNumber(int min, int max)

วิธีแรก — getRandomNumber(int max)— ส่งคืนตัวเลขสุ่มในช่วง0, 1, 2, ... max-1. ภายใต้ประทุนจะใช้Randomคลาสจากjava.utilแพ็คเกจ แต่นั่นจะไม่เปลี่ยนวิธีที่คุณใช้ตัวเลขสุ่ม

getRandomNumber(int)ยอมรับจำนวนเต็มเป็นอาร์กิวเมนต์ ตัวเลขนี้จะเป็นขอบเขตบนของตัวเลขที่ตัวสร้างตัวเลขสุ่มสามารถส่งคืนได้ ขอบเขตล่างคือ 0 โปรดทราบ! ตัวสร้างตัวเลขสุ่มจะไม่ส่งคืนค่าของขอบเขตบน ตัวอย่างเช่น ถ้าคุณเรียกgetRandomNumber(3)มันจะสุ่มกลับเป็น 0, 1 หรือ 2 อย่างที่คุณเห็น มันจะไม่ส่งกลับ 3 การใช้ตัวสร้างตัวเลขสุ่มด้วยวิธีนี้ค่อนข้างง่าย แต่ก็เหมาะสำหรับหลายๆ กรณี

วิธีที่สอง — getRandomNumber(int min, int max)— ส่งกลับจำนวนเต็มแบบสุ่มใน[min, max-1]ช่วง จะไม่ส่งคืนตัวเลขที่น้อยกว่าminและจะไม่ส่งคืนตัวเลขที่max-1มากกว่า

วิธีการเหล่านี้สามารถนำมาใช้ในทางปฏิบัติได้อย่างไร?

1. ลูกเต๋า

สมมติว่าคุณต้องการจำลองการทอยลูกเต๋าและรับตัวเลขสุ่มใน1-6ช่วง คุณจะทำอย่างไร? สามารถทำได้ด้วยโค้ดดังนี้:

int dice = getRandomNumber(1, 7);

1-6วิธี นี้จะส่งคืนจำนวนเต็มแบบสุ่มในช่วง

2. เป้าหมายการปฏิบัติ

สมมติว่าคุณต้องการจำลองการยิงไปที่เป้าหมาย และความแม่นยำของการยิงมีส่วนประกอบแบบสุ่มที่แตกต่างกันไปในช่วงตั้งแต่รวม-10ไป จนถึง +10สามารถทำได้ด้วยโค้ดดังนี้:

int dx = getRandomNumber(-10, 11);

วิธี นี้จะส่งคืนจำนวนเต็มแบบสุ่มในช่วง-10เป็น+10

มีหลายวิธีในการใช้ตัวเลขสุ่มในเกม คุณถูกจำกัดด้วยจินตนาการของคุณเท่านั้น เขียนเกมของคุณเอง ปรับแต่งเกม และสนุกไปกับกระบวนการนี้

ทุกคนสามารถเล่นเกมได้ แต่มีเพียงโปรแกรมเมอร์เท่านั้นที่สามารถสร้างเกมได้