CodeGym /จาวาบล็อก /สุ่ม /วิธีการเริ่มต้นในอินเทอร์เฟซ
John Squirrels
ระดับ
San Francisco

วิธีการเริ่มต้นในอินเทอร์เฟซ

เผยแพร่ในกลุ่ม
Java เวอร์ชันใหม่ทุกเวอร์ชันแตกต่างจากเวอร์ชันก่อนหน้า ต่อไปนี้คือตัวอย่างการเปลี่ยนแปลงเนื้อหาที่เรากล่าวถึง: ก่อน Java 5 ภาษาไม่มีenums วิธีการเริ่มต้นในอินเทอร์เฟซ - 1ในทำนองเดียวกัน Java 8 แตกต่างจาก Java 7 อย่างเห็นได้ชัด บทเรียนส่วนใหญ่ของเราเขียนขึ้นสำหรับเวอร์ชันที่ 7 ของภาษา แต่แน่นอนว่าเราจะไม่ละเลยนวัตกรรมที่สำคัญ เนื่องจากเราได้พูดถึงอินเทอร์เฟ ซในบทเรียนนี้แล้ว เราจะพิจารณาการอัปเดตหนึ่งรายการ นั่นคือวิธีเริ่มต้นในอินเทอร์เฟซ คุณรู้อยู่แล้วว่า อิน เทอร์เฟซไม่ได้ใช้ลักษณะการทำงาน หน้าที่ของมันคือการอธิบายลักษณะการทำงานที่ออบเจกต์ทั้งหมดที่ใช้งานต้องมี. แต่นักพัฒนามักพบสถานการณ์ที่การใช้งานเมธอดเหมือนกันในทุกคลาส ลองพิจารณาตัวอย่างรถเก่าของเรา:

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 gas() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class F1Car implements Car {
   @Override
   public void gas() {
       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 gas() {
       System.out.println("This car accelerates differently!");
   }

   @Override
   public void brake() {
       System.out.println("This car decelerates differently!");
   }
}
รถยนต์ประเภทอื่น ๆ ทั้งหมด 99 คันจะใช้วิธีเริ่มต้นและUnusualCarคลาสซึ่งเป็นข้อยกเว้นจะไม่ทำให้เสียภาพรวมและกำหนดพฤติกรรมของตัวเองอย่างใจเย็น การสืบทอดอินเทอร์เฟซหลายรายการ ดังที่คุณทราบแล้ว Java ไม่สนับสนุนการสืบทอดหลายรายการ มีเหตุผลหลายประการสำหรับเรื่องนี้ เราจะดูรายละเอียดในบทเรียนแยกต่างหาก รองรับภาษาอื่นๆ เช่น C++ หากไม่มีการสืบทอดหลายรายการ ปัญหาร้ายแรงจะเกิดขึ้น: วัตถุชิ้นหนึ่งสามารถมีลักษณะและ 'พฤติกรรม' ที่แตกต่างกันได้หลายอย่าง นี่คือตัวอย่างจากชีวิต: เราเป็นลูกของพ่อแม่ นักเรียนกับครู และคนไข้กับหมอของเรา ในชีวิต เรามีบทบาทที่แตกต่างกัน ดังนั้น จึงมีพฤติกรรมที่แตกต่างกัน แน่นอนว่าเราจะไม่พูดกับครูในลักษณะเดียวกับที่เราพูดกับเพื่อนสนิทของเรา ลองแปลสิ่งนี้เป็นรหัส ลองนึกภาพว่าเรามีสองคลาส: บ่อน้ำและกรงนกขนาดใหญ่ สำหรับสระน้ำ เราต้องการนกน้ำ สำหรับกรงนก เราต้องการนกที่บินได้ ในการทำเช่นนี้ เราได้สร้างคลาสพื้นฐานสองคลาส:FlyingBirdและWaterfowl.

public class Waterfowl {
}

public class FlyingBird {
}
ดังนั้น เราจะส่งนกที่มีคลาสสืบทอดFlyingBirdไปยังกรงนกใหญ่ และเราจะส่งนกที่สืบทอดWaterfowlไปยังบ่อน้ำ ทุกอย่างดูเหมือนง่ายมาก แต่เราจะส่งเป็ดไปที่ไหน? มันว่ายน้ำและบิน และเราไม่มีหลายมรดก โชคดีที่ Java รองรับการใช้งานอินเทอร์เฟซที่หลากหลาย แม้ว่าคลาสจะไม่สามารถสืบทอดพาเรนต์หลายตัวได้ แต่ก็สามารถใช้หลายอินเทอร์เฟซได้อย่างง่ายดาย! เป็ดของเราสามารถเป็นได้ทั้งนกบินและนกน้ำ :) เราเพียงแค่ต้องสร้างFlyingBirdและWaterfowlเชื่อมต่อมากกว่าชั้นเรียนเพื่อให้ได้ผลลัพธ์ที่ต้องการ

public class Duck implements FlyingBird, Waterfowl {

   // The methods of both interfaces can be easily combined into one class

   @Override
   public void fly() {
       System.out.println("Fly!");
   }

   @Override
   public void swim() {

       System.out.println("Swim!");
   }
}
ดังนั้น โปรแกรมของเราจึงรักษาความยืดหยุ่นของคลาสไว้ และเมื่อใช้ร่วมกับเมธอดดีฟอลต์ ความสามารถของเราในการกำหนดพฤติกรรมของอ็อบเจกต์จึงแทบไม่มีขีดจำกัด! :)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION