JavaRush /จาวาบล็อก /Random-TH /พื้นฐานของอินสแตนซ์และการสืบทอด

พื้นฐานของอินสแตนซ์และการสืบทอด

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

มรดกจาวา

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

   private String model;
   private int maxSpeed;
   private int yearOfManufacture;

   public Car(String model, int maxSpeed, int yearOfManufacture) {
       this.model = model;
       this.maxSpeed = maxSpeed;
       this.yearOfManufacture = yearOfManufacture;
   }
}

public class Truck extends Car {

   public Truck(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}

public class Sedan extends Car {
   public Sedan(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}
อย่างน้อยที่สุด เราได้หลีกเลี่ยงการทำซ้ำโค้ดโดยไม่จำเป็น และนี่คือสิ่งที่เราควรมุ่งมั่นเสมอเมื่อเขียนโปรแกรม นอกจากนี้ เรามีโครงสร้างคลาสที่เรียบง่ายและเข้าใจได้: ฟิลด์ที่ใช้ร่วมกับเครื่องจักรทั้งหมดจะอยู่ในคลาสเดียว ตัวอย่างเช่น หากรถบรรทุกมีฟิลด์เฉพาะที่รถคันอื่นไม่มี ก็สามารถประกาศไว้ในคลาสTruckได้ เช่นเดียวกับวิธีการต่างๆ รถยนต์ทุกคันมีพฤติกรรมบางอย่างที่เหมือนกันซึ่งสามารถอธิบายได้ เช่น สตาร์ทรถ เติมแก๊ส/เบรก ฯลฯ วิธีการทั่วไปเหล่านี้สามารถจัดอยู่ในคลาสทั่วไปCarและพฤติกรรมเฉพาะของแต่ละประเภทสามารถอธิบายได้ในคลาสสืบทอด
public class Car {

   public void gas() {
       //...gas
   }

   public void brake() {
       //...brake
   }
}


public class F1Car extends Car {

   public void pitStop() {

       //...only racing cars make pit stops
   }

   public static void main(String[] args) {

       F1Car formula1Car = new F1Car();
       formula1Car.gas();
       formula1Car.pitStop();
       formula1Car.brake();
   }
}
เราได้ย้ายวิธีการทั่วไปของรถทุกคันมาไว้ในชั้นเรียนCarแล้ว แต่ในคลาสผู้สืบทอดF1Carซึ่งอธิบายรถแข่ง Formula 1 - ป้ายหยุด (หยุดเพื่อการบำรุงรักษารถอย่างเร่งด่วน) ซึ่งทำในการแข่งรถเท่านั้นและมีความโดดเด่นด้วยพฤติกรรมเฉพาะ

ตัวดำเนินการอินสแตนซ์ Java

ในการตรวจสอบว่าวัตถุถูกสร้างขึ้นตามคลาสหรือไม่ มีตัวดำเนินการพิเศษใน Java instanceof- มันจะคืนค่าtrueหากการทดสอบเป็นจริงหรือfalseหากผลลัพธ์เป็นเท็จ มาดูกันว่ามันทำงานอย่างไรโดยใช้คลาสรถของเราเป็นตัวอย่าง:
public class Truck extends Car {

   public static void main(String[] args) {

       Truck truck = new Truck();
       System.out.println(truck instanceof Car);
   }
}
ผลลัพธ์: จริง เช็คโดยใช้ตัวดำเนินinstanceofการส่งคืนtrueเนื่องจากเรามีวัตถุของคลาสTruckและรถบรรทุกทั้งหมดเป็นรถยนต์ คลาสTruckเป็นผู้สืบทอดของคลาสCarดังนั้นรถบรรทุกทั้งหมดจึงถูกสร้างขึ้นโดยมีพื้นฐานมาจากรถยนต์ระดับกลางทั่วไป ให้ความสนใจกับตัวดำเนินการinstanceof: มันเขียนโดยไม่มีจุด เนื่องจากเป็นตัวดำเนินการ ไม่ใช่วิธีการ (“อินสแตนซ์ของวัตถุของคลาส”) เรามาลองแตกต่างออกไป:
public static void main(String[] args) {

   Car car = new Car();
   System.out.println(car instanceof Truck);
}
ผลลัพธ์: false คลาสCarและวัตถุของคลาสไม่ได้มาจากคลาสTruckรถบรรทุกทั้งหมดเป็นรถยนต์ แต่ไม่ใช่รถยนต์ทุกคันที่เป็นรถบรรทุก วัตถุCarไม่ได้ถูกสร้างขึ้นตามTruckคลาส อีกตัวอย่างหนึ่ง:
public static void main(String[] args) {

   Car car = new Car();
   Truck truck = new Truck();
   System.out.println(car instanceof Object && truck instanceof Object);
}
ผลลัพธ์: จริง ตรรกะที่นี่ก็เรียบง่ายเช่นกัน: คลาสทั้งหมดใน Java รวมถึงคลาสที่คุณสร้างขึ้นนั้นมาจากคลาสObject(แม้ว่าคุณจะไม่ได้เขียนส่วนขยาย Object ในคลาสเหล่านั้น - กลไกนี้มีนัยอยู่ในคลาสเหล่านั้น) เหตุใดสิ่งนี้จึงอาจมีประโยชน์และภายใต้สถานการณ์ใด การใช้โอเปอเรเตอร์ที่พบบ่อยที่สุดinstanceofคือการแทนที่equals()เมธอด ตัวอย่างเช่น นี่คือวิธีการนำไปใช้equalsในชั้นเรียนString:
public boolean equals(Object anObject) {
   if (this == anObject) {
       return true;
   }
   if (anObject instanceof String) {
       String anotherString = (String) anObject;
       int n = value.length;
       if (n == anotherString.value.length) {
           char v1[] = value;
           char v2[] = anotherString.value;
           int i = 0;
           while (n-- != 0) {
               if (v1[i] != v2[i])
                       return false;
               i++;
           }
           return true;
       }
   }
   return false;
}
ก่อนที่จะเปรียบเทียบสตริงกับอ็อบเจ็กต์ที่ส่งผ่าน วิธีการจะตรวจสอบ: อ็อบเจ็กต์ที่ส่งผ่านนั้นเป็นสตริงจริงหรือไม่ จากนั้นเขาก็เริ่มเปรียบเทียบคุณสมบัติของวัตถุสองชิ้น หากไม่มีการตรวจสอบนี้ คุณสามารถส่งออบเจ็กต์ใดๆ ที่มีค่าและความยาว ไปยังเมธอด และเปรียบเทียบกับสตริงได้ ซึ่งแน่นอนว่าอาจผิดได้
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION