สวัสดี! วันนี้เราจะมาดูหลักการหนึ่งของ Object Oriented Programming (OOP) กัน: Inheritance นอกจากนี้ เราจะศึกษาความสัมพันธ์ประเภทอื่นๆ ระหว่างคลาส: องค์ประกอบและการรวม หัวข้อนี้จะไม่ใช่เรื่องยาก: คุณได้พบการสืบทอดและตัวอย่างการสืบทอดมาแล้วหลายครั้งในบทเรียนที่ผ่านมา วันนี้สิ่งสำคัญคือการเสริมความรู้ของคุณตรวจสอบกลไกการสืบทอดโดยละเอียดยิ่งขึ้นและเรียกใช้ตัวอย่างอีกครั้ง :) ไปกันเถอะ!
การสืบทอดใน Java และข้อดีของมัน
อย่างที่คุณจำได้การสืบทอดเป็นกลไกที่ให้คุณอธิบายคลาสใหม่ตามคลาสที่มีอยู่ (คลาสพาเรนต์) ในการทำเช่นนั้น คลาสใหม่จะยืมคุณสมบัติและฟังก์ชันการทำงานของคลาสพาเรนต์ ลองนึกถึงตัวอย่างมรดกที่ให้ไว้ในบทที่แล้ว:
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 void gas() {
// Gas
}
public void brake() {
// Brake
}
}
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);
}
}
เรามีโปรแกรมที่เกี่ยวข้องกับการทำงานกับรถยนต์ประเภทต่างๆ แม้ว่าคุณจะไม่ใช่ผู้คลั่งไคล้ในรถยนต์ แต่คุณก็น่าจะรู้ว่ามีรถยนต์หลายประเภทในโลกนี้ :) ดังนั้น เราจะแยกคุณสมบัติทั่วไปของรถยนต์ออกเป็นคลาสหลักทั่วไปที่เรียกCar
ว่า แล้วรถทุกคันมีอะไรเหมือนกันบ้าง โดยไม่คำนึงถึงประเภทรถ? รถยนต์ทุกคันมีปีที่ผลิต ชื่อรุ่น และความเร็วสูงสุด เราใส่คุณสมบัติเหล่านี้ลงในช่องmodel
, maxSpeed
และ yearOfManufacture
สำหรับพฤติกรรมรถทุกคันสามารถเร่งและชะลอความเร็วได้ :) เรากำหนดลักษณะการทำงานนี้ในgas()
และbrake()
วิธีการ สิ่งนี้ให้ประโยชน์อะไรกับเราบ้าง? ประการแรก มันลดจำนวนรหัส แน่นอนเราสามารถทำได้โดยไม่ต้องใช้คลาสผู้ปกครอง แต่เนื่องจากรถแต่ละคันต้องสามารถเร่งความเร็วและชะลอความเร็วได้ เราจะต้องสร้างgas()
และbrake()
วิธีการใน คลาส Truck
, Sedan
, F1Car
และSportsCar
และในคลาสรถอื่นๆ ทุกคลาส ลองนึกดูว่าเราจะต้องเขียนโค้ดพิเศษอีกเท่าไร และอย่าลืมฟิลด์model
, maxSpeed
, และyearOfManufacture
: หากเรากำจัดคลาสพาเรนต์ เราจะต้องสร้างคลาสเหล่านั้นในคลาสรถแต่ละคัน! เมื่อเรามีคลาสรถสองสามคลาส จำนวนโค้ดที่ซ้ำกันจะร้ายแรงมาก การย้ายฟิลด์และเมธอดทั่วไป (เรียกอีกอย่างว่า "สถานะ" และ "พฤติกรรม") ไปยังคลาสพาเรนต์ช่วยให้เราประหยัดเวลาและพื้นที่ได้มาก ถ้าบางประเภทมีคุณสมบัติเฉพาะหรือวิธีการที่รถประเภทอื่นไม่มีก็ไม่ใช่เรื่องใหญ่ คุณสามารถสร้างพวกมันในคลาสที่สืบทอดมา แยกจากคนอื่นๆ ได้ตลอดเวลา
public class F1Car extends Car {
public void pitStop() {
// Only race cars make pit stops
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
ลองดูรถแข่งฟอร์มูล่าวันเป็นตัวอย่าง ซึ่งแตกต่างจาก "ญาติ" ของพวกเขา พวกเขามีพฤติกรรมที่ไม่เหมือนใคร - พวกเขาแวะพักเป็นระยะๆ สิ่งนี้ไม่รบกวนเรา เราได้อธิบายลักษณะการทำงานทั่วไปในCar
คลาสพาเรนต์แล้ว และสามารถเพิ่มพฤติกรรมเฉพาะของคลาสรองลงไปยังคลาสเหล่านั้นได้ เช่นเดียวกับฟิลด์: หากคลาสย่อยมีคุณสมบัติเฉพาะ เราจะประกาศฟิลด์เหล่านี้ภายในคลาสย่อยอย่างใจเย็นและไม่ต้องกังวล :) ความสามารถในการใช้รหัสซ้ำเป็นข้อได้เปรียบหลักของการสืบทอด สำหรับโปรแกรมเมอร์ สิ่งสำคัญคือต้องไม่เขียนโค้ดเพิ่มเติม คุณจะพบสิ่งนี้ซ้ำ ๆ ในการทำงานของคุณ โปรดจำสิ่งอื่นที่สำคัญ: Java ไม่มีการสืบทอดหลายรายการ. แต่ละคลาสจะสืบทอดเพียงคลาสเดียวเท่านั้น เราจะพูดถึงสาเหตุของเรื่องนี้มากขึ้นในบทเรียนต่อๆ ไป สำหรับตอนนี้เพียงแค่จำไว้ อย่างไรก็ตาม สิ่งนี้ทำให้ Java แตกต่างจากภาษา OOP อื่นๆ บางภาษา ตัวอย่างเช่น C++ รองรับการสืบทอดหลายรายการ ทุกอย่างชัดเจนมากหรือน้อยด้วยมรดก เดินหน้าต่อไป
องค์ประกอบและการรวม
คลาสและวัตถุสามารถเชื่อมโยงเข้าด้วยกันได้ การสืบทอดอธิบายถึงความสัมพันธ์แบบ "is-a" สิงโตเป็นสัตว์ ความสัมพันธ์ดังกล่าวแสดงได้ง่ายโดยใช้การสืบทอด คลาสพาเรนต์อยู่ที่ไหนAnimal
และคลาสย่อยLion
คือที่ไหน อย่างไรก็ตาม ไม่ใช่ทุกความสัมพันธ์ที่อธิบายด้วยวิธีนี้ ตัวอย่างเช่น แป้นพิมพ์เกี่ยวข้องกับคอมพิวเตอร์อย่างแน่นอนแต่ไม่ใช่คอมพิวเตอร์ มือมีความเกี่ยวข้องกับบุคคล แต่ก็ไม่ใช่บุคคล ในกรณีเหล่านี้ เรามีความสัมพันธ์อีกประเภทหนึ่ง: ไม่ใช่ "is-a" แต่เป็น "has-a" มือไม่ใช่คน แต่เป็นส่วนหนึ่งของคน แป้นพิมพ์ไม่ใช่คอมพิวเตอร์ แต่เป็นส่วนหนึ่งของคอมพิวเตอร์ ความสัมพันธ์แบบ has-a สามารถอธิบายได้ในรหัสโดยใช้องค์ประกอบและการรวม. ความแตกต่างอยู่ที่ "ความเข้มงวด" ของความสัมพันธ์ ลองยกตัวอย่างง่ายๆ: เรามีชั้นCar
เรียน รถทุกคันมีเครื่องยนต์ อีกทั้งรถทุกคันมีผู้โดยสาร อะไรคือความแตกต่างพื้นฐานระหว่าง the Engine engine
และPassenger[] passengers
field? การที่ผู้โดยสารA
นั่งอยู่ในรถไม่ได้หมายความว่ามีผู้โดยสารB
และC
ไม่ได้อยู่ในรถ รถยนต์สามารถรองรับผู้โดยสารได้หลายคน ยิ่งไปกว่านั้น หากผู้โดยสารทุกคนลงจากรถ รถจะยังคงทำงานได้อย่างราบรื่น ความสัมพันธ์ระหว่างCar
คลาสและPassenger[] passengers
อาร์เรย์นั้นเข้มงวดน้อยกว่า เรียกว่าการรวมตัว เป็นอีกตัวอย่างที่ดีของการรวม สมมติว่าเรามีStudent
คลาสและStudentGroup
ระดับ. นักเรียนสามารถเข้าร่วมองค์กรนักเรียนได้หลายองค์กร: ชมรมฟิสิกส์ ชมรมแฟนคลับ Star Wars และ/หรือชมรมตลกสำหรับนักศึกษา องค์ประกอบเป็นความสัมพันธ์ที่เข้มงวดมากขึ้น เมื่อใช้การจัดองค์ประกอบ วัตถุจะเป็นส่วนหนึ่งของวัตถุบางอย่างและไม่สามารถอยู่ในวัตถุประเภทเดียวกันได้อีก ตัวอย่างที่ง่ายที่สุดคือเครื่องยนต์ของรถยนต์ เครื่องยนต์เป็นส่วนหนึ่งของรถยนต์และไม่สามารถเป็นส่วนหนึ่งของรถคันอื่นได้ อย่างที่คุณเห็น ความสัมพันธ์ของพวกเขาเข้มงวดกว่าความสัมพันธ์ระหว่าง Car
และPassengers
อ่านเพิ่มเติม: |
---|
GO TO FULL VERSION