Java เวอร์ชันใหม่แต่ละเวอร์ชันแตกต่างจากเวอร์ชันก่อนหน้า ตัวอย่างของการเปลี่ยนแปลงดังกล่าวจากเนื้อหาที่เรากล่าวถึง ภาษานั้นไม่มีมา
ดังนั้น Java 8 จึงแตกต่างจาก Java 7 อย่างเห็นได้ชัด แน่นอนว่าเราจะไม่ละเลยนวัตกรรมที่สำคัญ เนื่องจากเรากำลังพูดถึงอินเทอร์เฟซในบทเรียนนี้ ลองพิจารณาการอัปเดตภาษาหนึ่งรายการ: เมธอดเริ่มต้นในอินเทอร์เฟซ คุณรู้อยู่แล้วว่า อิน เทอร์เฟซไม่ได้ใช้ลักษณะการทำงาน จุดประสงค์คือเพื่ออธิบายพฤติกรรมที่ต้องมีอยู่ในวัตถุทั้งหมดที่ใช้อินเทอร์เฟซ แต่นักพัฒนามักพบสถานการณ์ที่การนำเมธอดมาใช้เหมือนกันในทุกคลาส ลองดูตัวอย่างรถเก่าของเรา:
enums
ก่อน Java 5
public interface Car {
public void gas();
public void brake();
}
public class Sedan implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class Truck implements Car {
@Override
public void go() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class F1Car implements Car {
@Override
public void go() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
คุณคิดว่าปัญหาหลักของรหัสนี้คืออะไร คุณอาจสังเกตเห็นว่าเราเขียนโค้ดซ้ำกันหลายชุด! นี่เป็นปัญหาทั่วไปในการเขียนโปรแกรมและควรหลีกเลี่ยง เป็นอีกเรื่องหนึ่งที่ไม่มีวิธีแก้ปัญหาเฉพาะก่อนการเปิดตัว Java 8 เมื่อเวอร์ชันนั้นออกมา มันเป็นไปได้ที่จะกำหนดเมธอดเริ่มต้นและนำไปใช้โดยตรงภายในอินเทอร์เฟซ! นี่คือวิธีการ:
public interface Car {
public default void gas() {
System.out.println("Gas!");
}
public default void brake() {
System.out.println("Brake!");
}
}
public class Sedan implements Car {
}
public class Truck implements Car {
}
public class F1Car implements Car {
}
ขณะนี้gas()
และbrake()
วิธีการ ซึ่งเหมือนกันสำหรับรถยนต์ทุกคัน ถูกย้ายไปยังอินเทอร์เฟซ ทำให้ไม่ต้องใช้รหัสซ้ำ และวิธีการที่มีอยู่ในแต่ละชั้นเรียน!
public class Main {
public static void main(String[] args) {
F1Car f1Car = new F1Car();
Sedan sedan = new Sedan();
Truck truck = new Truck();
truck.gas();
sedan.gas();
f1Car.brake();
}
}
จะเกิดอะไรขึ้นถ้ามี 100 คลาสที่มีgas()
เมธอด แต่มีเพียง 99 คลาสเท่านั้นที่ควรมีพฤติกรรมเดียวกัน นั่นทำให้เสียทุกอย่างหรือไม่? วิธีการเริ่มต้นจะใช้ไม่ได้ในกรณีนี้หรือไม่ ไม่แน่นอน :) วิธีการเริ่มต้นของอินเทอร์เฟซสามารถแทนที่ได้
public class UnusualCar implements Car {
@Override
public void go() {
System.out.println("This car accelerates differently!");
}
@Override
public void brake() {
System.out.println("This car slows down differently!");
}
}
รถยนต์อีก 99 ประเภทจะใช้วิธีเริ่มต้น ในขณะที่UnusualCar
ชั้นเป็นข้อยกเว้น มันจะกำหนดพฤติกรรมของมันเองอย่างสงบโดยไม่ทำลายภาพรวม การสืบทอดหลายรายการในอินเทอร์เฟซ ดังที่คุณทราบแล้ว ไม่มีการสืบทอดหลายรายการใน Java มีเหตุผลหลายประการสำหรับเรื่องนี้ เราจะพิจารณารายละเอียดในบทเรียนแยกต่างหาก ในภาษาอื่นๆ เช่น C++ สถานการณ์จะกลับกัน ไม่มีการสืบทอดหลายรายการที่นำเสนอความท้าทายที่ร้ายแรง เนื่องจากวัตถุเดียวกันสามารถมีลักษณะและพฤติกรรมที่แตกต่างกันได้หลายอย่าง ตัวอย่างเช่น เราเป็นลูกของพ่อแม่ นักเรียนกับครู และคนไข้กับหมอของเรา ในชีวิตจริง เราสวมบทบาทต่างๆ กัน ดังนั้น จึงมีพฤติกรรมที่แตกต่างกันไป เห็นได้ชัดว่าเรามีปฏิสัมพันธ์กับครูแตกต่างจากเพื่อนสนิท ลองแปลสถานการณ์นี้เป็นรหัส สมมติว่าเรามีสองชั้นเรียน: บ่อและกรงนก สระน้ำต้องการนกว่ายน้ำ ในขณะที่กรงนกต้องการนกที่บินได้ เพื่อแสดงสิ่งนี้ เราสร้างคลาสพื้นฐานสองคลาส:FlyingBird
และWaterfowl
.
public class Waterfowl {
}
public class FlyingBird {
}
ดังนั้นเราจะส่งนกที่สืบทอดFlyingBird
ไปยังกรงนกในขณะที่นกที่มาจากWaterfowl
จะไปที่สระน้ำ ทุกอย่างดูเหมือนตรงไปตรงมา แต่เราควรทำอย่างไรหากต้องการกำหนดเป็ดที่ไหนสักแห่ง เป็ดทั้งว่ายน้ำและบิน แต่เราไม่มีมรดกหลายรายการ โชคดีที่ Java รองรับการใช้งานอินเทอร์เฟซที่หลากหลาย หากคลาสไม่สามารถสืบทอดพาเรนต์หลายตัวได้ การใช้อินเทอร์เฟซหลายตัวเป็นเรื่องง่าย! เป็ดของเราสามารถเป็นนกบินได้เช่นเดียวกับนกว่ายน้ำ :) เพื่อให้ได้ผลลัพธ์ตามที่ต้องการ สิ่งที่เราต้องทำคือสร้างFlyingBird
และWaterfowl
เชื่อมต่อมากกว่าคลาส
public class Duck implements FlyingBird, Waterfowl {
// Methods of both interfaces combine easily into one class
@Override
public void fly() {
System.out.println("Flying!");
}
@Override
public void swim() {
System.out.println("Swimming!");
}
}
ซึ่งหมายความว่าโปรแกรมของเรายังคงความสามารถในการจัดการชั้นเรียนได้อย่างยืดหยุ่น เมื่อเรารวมสิ่งนั้นเข้ากับเมธอดเริ่มต้น ความสามารถของเราในการกำหนดพฤติกรรมของอ็อบเจกต์แทบจะไร้ขีดจำกัด! :)
GO TO FULL VERSION