สวัสดี! วันนี้เราจะมาดูหลักการอีกประการหนึ่งของการเขียนโปรแกรมเชิงวัตถุ (OOP) - การสืบทอด ในเวลาเดียวกัน เราจะศึกษาความสัมพันธ์ประเภทอื่นระหว่างคลาส - องค์ประกอบและการรวมกลุ่ม หัวข้อนี้จะไม่ใช่เรื่องยาก: คุณได้พบกับมรดกและตัวอย่างหลายครั้งในการบรรยายครั้งก่อน วันนี้สิ่งสำคัญคือการรวบรวมความรู้ของคุณ มาดูกลไกการสืบทอดให้ละเอียดยิ่งขึ้น และลองดูตัวอย่างอีกครั้ง :) ลุยเลย!
การสืบทอดใน 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
ในคลาสSportcar
และในคลาสอื่น ๆ ของรถยนต์ ลองนึกภาพว่าในกรณีนี้เราจะเขียนโค้ดพิเศษจำนวนเท่าใด อย่าลืมเกี่ยวกับฟิลด์ model, maxSpeed และ yearOfManufacture: หากเราละทิ้งคลาสพาเรนต์ เราจะสร้างมันขึ้นมาในแต่ละคลาสของเครื่อง! เมื่อเรามีแมชชีนคลาสจำนวนหลายสิบคลาส จำนวนโค้ดที่ซ้ำกันจะกลายเป็นเรื่องร้ายแรง การย้ายฟิลด์และวิธีการทั่วไป (หรือที่เรียกว่า "สถานะ" และ "พฤติกรรม") ไปยังคลาสพาเรนต์จะช่วยให้เราประหยัดเวลาและพื้นที่ได้มาก หากประเภทใดมีคุณสมบัติหรือวิธีการเฉพาะและไม่มีอยู่ในเครื่องจักรประเภทอื่น ก็ไม่สำคัญ สามารถสร้างได้ในคลาสสืบทอดเสมอ โดยแยกจากคลาสอื่นๆ ทั้งหมด
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();
}
}
ยกตัวอย่างรถแข่ง Formula 1 พวกเขาไม่เหมือน "ญาติ" มีพฤติกรรมที่เป็นเอกลักษณ์ - พวกเขาแวะพักเป็นครั้งคราว สิ่งนี้ไม่รบกวนเรา เราได้อธิบายพฤติกรรมทั่วไปในคลาส parent แล้วCar
และเราสามารถเพิ่มพฤติกรรมเฉพาะของคลาสย่อยภายในคลาสได้ นอกจากนี้ยังใช้กับฟิลด์ต่างๆ ด้วย: หากคลาสย่อยมีคุณสมบัติเฉพาะ เราสามารถประกาศฟิลด์เหล่านี้ภายในคลาสนั้นได้อย่างใจเย็นและไม่ต้องกังวล :) ความสามารถในการนำโค้ดกลับมาใช้ใหม่ถือเป็นข้อได้เปรียบหลักของการสืบทอด มันสำคัญมากสำหรับโปรแกรมเมอร์ที่จะไม่เขียนโค้ดในปริมาณที่ไม่จำเป็น คุณจะพบสิ่งนี้มากกว่าหนึ่งครั้งในการทำงานของคุณ โปรดจำอีกสิ่งหนึ่งที่สำคัญมาก: Java ไม่มีการสืบทอดหลายรายการ แต่ละคลาสสืบทอดมาจากคลาสเดียวเท่านั้น เราจะพูดถึงเหตุผลนี้โดยละเอียดมากขึ้นในการบรรยายครั้งต่อๆ ไป แต่ตอนนี้แค่จำไว้ สิ่งนี้ทำให้ Java แตกต่างจากภาษา OOP อื่นๆ ตัวอย่างเช่น C++ มีมรดกหลายรายการ ทุกอย่างชัดเจนไม่มากก็น้อยเกี่ยวกับการสืบทอด - มาดูกันดีกว่า
องค์ประกอบและการรวมกลุ่ม
คลาสและอ็อบเจ็กต์สามารถเชื่อมโยงถึงกัน มรดกอธิบายความสัมพันธ์ "เป็น" (หรือในภาษาอังกฤษ "IS A") ลีโอเป็นสัตว์ ความสัมพันธ์นี้สามารถแสดงได้อย่างง่ายดายโดยใช้การสืบทอด โดยที่Animal
คลาสจะเป็นผู้ปกครองและLion
คลาสจะเป็นลูก อย่างไรก็ตาม ไม่ใช่ทุกความสัมพันธ์ในโลกนี้ที่อธิบายไว้ในลักษณะนี้ ตัวอย่างเช่น แป้นพิมพ์เชื่อมต่อกับคอมพิวเตอร์ในทางใดทางหนึ่งอย่างแน่นอน แต่ไม่ใช่คอมพิวเตอร์ มือมีความเชื่อมโยงกับบุคคลแต่ไม่ใช่บุคคล ในกรณีเหล่านี้ ขึ้นอยู่กับความสัมพันธ์ประเภทอื่น: ไม่ใช่ "เป็น" แต่ "เป็นส่วนหนึ่งของ" ("HAS A") มือไม่ใช่คน แต่เป็นส่วนหนึ่งของคน แป้นพิมพ์ไม่ใช่คอมพิวเตอร์ แต่เป็นส่วนหนึ่งของคอมพิวเตอร์ ความ สัมพันธ์HAS A สามารถอธิบายได้ในโค้ดโดยใช้ กลไก การจัดองค์ประกอบและการรวมกลุ่ม ความแตกต่างระหว่างพวกเขาอยู่ที่ "ความเข้มงวด" ของการเชื่อมต่อเหล่านี้ ขอยกตัวอย่างง่ายๆ: เรามีCar
รถ ของเรา รถทุกคันมีเครื่องยนต์ นอกจากนี้รถทุกคันยังมีผู้โดยสารอยู่ข้างใน ความแตกต่างพื้นฐานระหว่างสาขาEngine engine
และ คืออะไร Passenger [] passengers
? หากรถยนต์มีผู้โดยสารอยู่ภายในไม่А
ได้หมายความว่าจะไม่มีผู้โดยสารอยู่ในB
นั้น C
รถยนต์หนึ่งคันสามารถรองรับผู้โดยสารได้หลายคน นอกจากนี้หากนำผู้โดยสารทั้งหมดออกจากรถก็จะยังคงทำงานอย่างเงียบ ๆ ความสัมพันธ์ระหว่างชั้นเรียนCar
และจำนวนผู้โดยสารPassenger [] passengers
มีความเข้มงวดน้อยกว่า มันเรียกว่าการรวมตัว มีบทความดีๆ ในหัวข้อนี้: ความสัมพันธ์ระหว่างคลาส (วัตถุ) . เป็นอีกตัวอย่างที่ดีของการรวมกลุ่ม สมมติว่าเรามีชั้นเรียนStudent
ที่แสดงถึงนักเรียน และชั้นเรียนStudentsGroup
(กลุ่มนักเรียน) นักเรียนสามารถเป็นสมาชิกของชมรมฟิสิกส์ แฟนคลับของนักเรียน Star Wars หรือทีม KVN องค์ประกอบเป็นการสื่อสารประเภทที่เข้มงวดมากขึ้น เมื่อใช้การจัดองค์ประกอบ วัตถุไม่เพียงแต่เป็นส่วนหนึ่งของวัตถุบางอย่างเท่านั้น แต่ยังไม่สามารถเป็นของวัตถุประเภทเดียวกันได้อีก ตัวอย่างที่ง่ายที่สุดคือเครื่องยนต์ของรถยนต์ เครื่องยนต์เป็นส่วนหนึ่งของรถยนต์ แต่ไม่สามารถเป็นส่วนหนึ่งของรถคันอื่นได้ อย่างที่คุณเห็น การเชื่อมต่อของพวกเขาเข้มงวดกว่าของและ Car
มากPassengers
GO TO FULL VERSION