CodeGym /จาวาบล็อก /สุ่ม /ตัวอย่างเฉพาะของคลาสนามธรรมใน Java
John Squirrels
ระดับ
San Francisco

ตัวอย่างเฉพาะของคลาสนามธรรมใน Java

เผยแพร่ในกลุ่ม
สวัสดี! ในบทเรียนที่ผ่านมา เราได้พบกับอินเทอร์เฟซและเข้าใจว่ามีไว้เพื่ออะไร หัวข้อของวันนี้จะสะท้อนถึงหัวข้อก่อนหน้า พูดคุยเกี่ยวกับคลาสนามธรรมใน Java ตัวอย่างเฉพาะของคลาสนามธรรมใน Java - 1

ทำไมชั้นเรียนถึงเรียกว่า 'นามธรรม'

คุณคงจำได้ว่า 'สิ่งที่เป็นนามธรรม' คืออะไร เราได้อธิบายไปแล้ว :) ถ้าลืมก็อย่ากลัว ข้อควรจำ: เป็นหลักการของ OOPที่กล่าวว่าเมื่อออกแบบคลาสและสร้างออบเจกต์ เราควรระบุเฉพาะคุณสมบัติหลักของเอนทิตีและละทิ้งคุณสมบัติรอง ตัวอย่างเช่น หากเรากำลังออกแบบSchoolTeacherคลาส เราแทบจะไม่ต้องการคุณสมบัติ ' ความสูง ' เลย แท้จริงแล้วคุณสมบัตินี้ไม่เกี่ยวข้องกับครู แต่ถ้าเรากำลังสร้างBasketballPlayerชั้นเรียน การเติบโตจะเป็นคุณลักษณะที่สำคัญ ดังนั้นจงฟัง คลาสนามธรรมเป็นนามธรรมอย่างที่เป็นมา — เป็น 'ช่องว่าง' ที่ยังไม่เสร็จสำหรับกลุ่มชั้นเรียนในอนาคต ไม่สามารถใช้ช่องว่างได้ตามที่เป็นอยู่ มัน 'ดิบ' เกินไป แต่มันอธิบายสถานะบางอย่างและพฤติกรรมทั่วไปที่จะถูกครอบงำโดยคลาสในอนาคตที่สืบทอดคลาสนามธรรม

ตัวอย่างของคลาส Java ที่เป็นนามธรรม

พิจารณาตัวอย่างง่ายๆ กับรถยนต์:

public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
นี่คือลักษณะของคลาสนามธรรมที่ง่ายที่สุด อย่างที่คุณเห็น มันไม่มีอะไรพิเศษ :) ทำไมเราถึงต้องการมัน? ประการแรก มันอธิบายสิ่งที่จำเป็นของเรา รถยนต์ ในลักษณะที่เป็นนามธรรมที่สุดเท่าที่จะเป็นไปได้ มีเหตุผลที่เราใช้คำว่านามธรรม ในโลกแห่งความเป็นจริง ไม่มี 'รถยนต์ที่เป็นนามธรรม' มีทั้งรถบรรทุก รถแข่ง ซีดาน คูเป้ และเอสยูวี คลาสนามธรรมของเราเป็นเพียง 'พิมพ์เขียว' เราจะใช้ในภายหลังเพื่อสร้างคลาสรถยนต์

public class Sedan extends Car {

   @Override
   public void gas() {
       System.out.println("The sedan is accelerating!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan is slowing down!");
   }

}
สิ่งนี้คล้ายกับสิ่งที่เราพูดถึงในบทเรียนเรื่องมรดก แต่ในบทเรียนเหล่านั้น เรามีคลาส Car และวิธีการของมันก็ไม่เป็นนามธรรม แต่วิธีแก้ปัญหานั้นมีข้อเสียหลายประการที่ได้รับการแก้ไขในคลาสนามธรรม ก่อนอื่นคุณไม่สามารถสร้างอินสแตนซ์ของคลาสนามธรรม :

public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
ผู้สร้างของ Java ออกแบบ 'คุณสมบัติ' นี้โดยเฉพาะ ขอเตือนอีกครั้งว่าคลาสนามธรรมเป็นเพียงพิมพ์เขียวสำหรับคลาส 'ปกติ' ในอนาคต คุณไม่ต้องการสำเนาพิมพ์เขียวใช่ไหม และคุณไม่ได้สร้างอินสแตนซ์ของคลาสนามธรรม :) แต่ถ้าCarคลาสนั้นไม่ใช่นามธรรม เราสามารถสร้างอินสแตนซ์ของมันได้ง่ายๆ:

public class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       // Some logic
   }

    public void brake() {
       // Some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Everything is fine. A car is created.
   }
}
ตอนนี้โปรแกรมของเรามีรถบางประเภทที่ไม่สามารถเข้าใจได้ — มันไม่ใช่รถบรรทุก ไม่ใช่รถแข่ง ไม่ใช่รถซีดาน และมันไม่ชัดเจนเลยว่ามันคืออะไร นี่คือ 'รถยนต์นามธรรม' ที่ไม่มีอยู่ในธรรมชาติ เราสามารถให้ตัวอย่างเดียวกันโดยใช้สัตว์ ลองนึกภาพว่าถ้าAnimalคลาส( สัตว์ที่เป็นนามธรรม ) ไม่ทราบแน่ชัดว่าเป็นสัตว์ชนิดใด อยู่ในตระกูลใด และมีลักษณะอย่างไร มันคงเป็นเรื่องแปลกที่จะเห็นว่าในโปรแกรมของคุณ ไม่มี 'สัตว์ที่เป็นนามธรรม' ในธรรมชาติ เฉพาะสุนัข แมว สุนัขจิ้งจอก ตัวตุ่น ฯลฯ คลาสนามธรรมนำเราออกจากวัตถุนามธรรม พวกเขาให้สถานะและพฤติกรรมพื้นฐานแก่เรา ตัวอย่างเช่น รถยนต์ทุกคันควรมีรุ่นสีและความเร็วสูงสุดและคุณควรจะสามารถใช้แก๊สและเบรก _ แค่นั้นแหละ. นี่คือแผนนามธรรมทั่วไป ต่อไปคุณออกแบบชั้นเรียนที่คุณต้องการ หมายเหตุ:สองเมธอดในคลาสนามธรรมถูกกำหนดให้เป็นabstract เช่นกัน และไม่มีการใช้งานใดๆ เหตุผลก็เหมือนกัน: คลาสนามธรรมไม่ได้สร้างพฤติกรรมเริ่มต้นสำหรับรถนามธรรม พวกเขาแค่ระบุว่ารถทุกคันควรทำอะไรได้บ้าง อย่างไรก็ตาม ถ้าคุณต้องการพฤติกรรมเริ่มต้น คุณสามารถใช้เมธอดในคลาสนามธรรมได้ Java ไม่ได้ห้ามสิ่งนี้:

public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Gas!");
   }

   public abstract void brake();

   // Getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan is slowing down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
เอาต์พุตของคอนโซล: “Gas!” อย่างที่คุณเห็น เราได้ปรับใช้เมธอดแรกในคลาสนามธรรม ไม่ใช่วิธีที่สอง ด้วยเหตุนี้Sedanพฤติกรรมของคลาสของเราจึงแบ่งออกเป็นสองส่วน: หากคุณเรียกใช้gas()เมธอด 'เพิ่มขึ้น' จนถึงCarคลาสแม่ที่เป็นนามธรรม แต่เราแทนที่เมธอดbrake()ในSedanคลาส สิ่งนี้กลายเป็นสิ่งที่สะดวกและยืดหยุ่นมาก แต่ตอนนี้คลาสของเราไม่เป็นนามธรรมแล้ว ท้ายที่สุด เมธอดครึ่งหนึ่งถูกนำไปใช้ นี่ เป็นคุณสมบัติที่สำคัญมาก - คลาสเป็นนามธรรมหากอย่างน้อยหนึ่งในวิธีการนั้นเป็นนามธรรม. วิธีใดวิธีหนึ่งจากสองวิธี หรืออย่างน้อยหนึ่งวิธีจากทั้งหมดพันวิธี — มันไม่สร้างความแตกต่าง เรายังสามารถนำวิธีการทั้งหมดไปใช้โดยไม่ปล่อยให้เป็นนามธรรม จากนั้นจะเป็นคลาสนามธรรมโดยไม่มีวิธีการนามธรรม โดยหลักการแล้ว สิ่งนี้เป็นไปได้ และคอมไพเลอร์จะไม่สร้างข้อผิดพลาด แต่ควรหลีกเลี่ยงจะดีกว่า: คำว่านามธรรมจะสูญเสียความหมายไป และเพื่อนโปรแกรมเมอร์ของคุณจะประหลาดใจมาก :/ ในขณะเดียวกันหากวิธีการถูกทำเครื่องหมายไว้ ด้วยคำว่านามธรรม แต่ละคลาสย่อยจะต้องดำเนินการหรือประกาศเป็นนามธรรม มิฉะนั้น คอมไพเลอร์จะสร้างข้อผิดพลาด แน่นอน แต่ละคลาสสามารถสืบทอดคลาสนามธรรมได้เพียงคลาสเดียว ดังนั้นในแง่ของการสืบทอด ไม่มีความแตกต่างระหว่างคลาสนามธรรมและคลาสธรรมดา ไม่สำคัญว่าเราจะสืบทอดคลาสนามธรรมหรือคลาสธรรมดา สามารถมีคลาสพาเรนต์ได้เพียงคลาสเดียวเท่านั้น

เหตุใด Java จึงไม่มีการสืบทอดหลายคลาส

เราได้กล่าวไปแล้วว่า Java ไม่มีการสืบทอดหลายรายการ แต่เรายังไม่ได้สำรวจว่าทำไม ลองทำกันตอนนี้ ความจริงก็คือ หาก Java มีการสืบทอดหลายรายการ คลาสลูกจะไม่สามารถตัดสินใจได้ว่าควรเลือกพฤติกรรมใด สมมติว่าเรามีสองคลาส — ToasterและNuclearBomb:

public class Toaster {


 public void on() {

       System.out.println("The toaster is on. Toast is being prepared!");
   }

   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Boom!");
   }
}
อย่างที่คุณเห็น ทั้งสองมีon()วิธีการ สำหรับเครื่องปิ้งขนมปัง สำหรับระเบิดนิวเคลียร์ มันทำให้เกิดการระเบิด อุ๊ปส์: / ลองจินตนาการว่าคุณตัดสินใจ (อย่าถามฉันว่าทำไม!) ที่จะสร้างบางสิ่งระหว่างนั้น และทำให้คุณมีMysteriousDeviceคลาส! แน่นอนว่าโค้ดนี้ใช้ไม่ได้และเราให้ไว้เป็นตัวอย่าง 'แต่อาจเป็นได้' เท่านั้น:

public class MysteriousDevice extends Toaster, NuclearBomb {

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // So what should happen here? Do we get toast or a nuclear apocalypse?
   }
}
เรามาดูกันดีกว่าว่ามีอะไรบ้าง อุปกรณ์ลึกลับนี้สืบทอด Toaster และ NuclearBomb พร้อมกัน ทั้งสองมีon()วิธีการ ดังนั้น หากเราเรียกon()ใช้เมธอด ก็ไม่ชัดเจนว่าควรเรียกใช้เมธอดใดบนMysteriousDeviceออบเจกต์ ไม่มีทางที่วัตถุจะรู้ได้เลย และเหนือสิ่งอื่นใด: NuclearBomb ไม่มีoff()วิธีการ ดังนั้นหากเราเดาไม่ถูก ก็จะไม่สามารถปิดการใช้งานอุปกรณ์ได้ ตัวอย่างเฉพาะของคลาสนามธรรมใน Java - 2เป็นเพราะ 'ความสับสน' ที่วัตถุไม่รู้ว่าจะแสดงพฤติกรรมใด ผู้สร้าง Java จึงละทิ้งการสืบทอดหลายรายการ อย่างไรก็ตาม คุณจะจำได้ว่าคลาส Java สามารถใช้หลายอินเทอร์เฟซได้ อย่างไรก็ตาม ในการศึกษาของคุณ คุณได้พบคลาสนามธรรมอย่างน้อยหนึ่งคลาสแล้ว!

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
มันเป็นเพื่อนเก่าของคุณCalendarชั้นเรียน เป็นนามธรรมและมีลูกหลายคน หนึ่งในนั้นGregorianCalendarคือ คุณใช้มันไปแล้วในบทเรียนเกี่ยวกับวันที่ :) ทุกอย่างชัดเจนเพียงพอ มีเพียงคำถามเดียว: อะไรคือความแตกต่างพื้นฐานระหว่างคลาสนามธรรมและอินเทอร์เฟซ เหตุใดพวกเขาจึงเพิ่มทั้งสองอย่างลงใน Java แทนที่จะจำกัดเพียงภาษาเดียว ท้ายที่สุดนั่นก็เพียงพอแล้ว เราจะพูดถึงเรื่องนี้ในบทเรียนหน้า ! จนกระทั่ง :)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION