ฉันจะปฏิเสธการเข้าถึงวิธีการของซูเปอร์คลาสได้อย่างไร

ฉันสงสัยว่าฉันจะปฏิเสธการเข้าถึงวิธีการของซูเปอร์คลาสของคลาสได้อย่างไร

ตัวอย่าง: ฉันมีคลาส Door และคลาส Emptyness ซึ่งโดยพื้นฐานแล้วเป็นเพียงประตูที่เปิดสำหรับแอปพลิเคชันของฉัน ตอนนี้ฉันต้องการสืบทอดวิธีการประตูส่วนใหญ่ แต่ฉันไม่ต้องการให้ผู้ใช้สามารถเรียก 'ประตูปิด' วิธีความว่างเปล่า ทำอย่างไร?


person Samuel    schedule 17.04.2011    source แหล่งที่มา
comment
ทำให้วิธีการเป็นแบบส่วนตัวหรือไม่?   -  person Marnix    schedule 17.04.2011
comment
แต่กว่าที่ผู้ใช้ก็ไม่สามารถเรียกมันว่าประตูได้เช่นกัน?   -  person Samuel    schedule 17.04.2011


คำตอบ (5)


ดูเหมือนว่า Emptyness ล้มเหลวในการทดสอบ "ฉันควรเป็นคลาสย่อย" ที่เกี่ยวข้องกับ Door การทดสอบคือประโยคต่อไปนี้เป็นจริง: Emptyness คือ Door เนื่องจาก Door สามารถปิดได้ Emptyness จึงไม่เป็นไปตามข้อกำหนดดังกล่าว

แนะนำให้ใช้การรวมกลุ่มมากกว่าการสืบทอด ให้ Emptyness ใช้อินเทอร์เฟซของตนเอง (หรืออินเทอร์เฟซอื่นๆ ที่เกี่ยวข้อง แต่ไม่ใช่ Door) และ มี อินสแตนซ์ Door ที่ใช้เพื่อตอบสนองการดำเนินการที่เกี่ยวข้อง

การทำบางอย่างเช่นการแทนที่การดำเนินการ close โดยที่ไม่ทำอะไรเลยหรือโยนข้อยกเว้นนั้นไม่เหมาะสมอย่างยิ่ง เว้นแต่ Door#close ถูกกำหนดว่าเป็นทางเลือก (ผ่านแท็ก throws สำหรับข้อยกเว้นที่เกี่ยวข้อง) (และระวังการดำเนินการ "เป็นทางเลือก" ในลำดับชั้นของคลาส ซึ่งมักจะบ่งบอกถึงปัญหาการออกแบบ ไม่จำเป็นเสมอไป แต่โดยทั่วไป) ตัวอย่างที่ Andreas ให้ Iterator#remove เช่น: Iterator#remove ถูกแท็กว่ากำลังขว้าง UnsupportedOperationException หาก Door#close ถูกแท็กในลักษณะนั้น และหากคุณพอใจกับวิธีการดังกล่าว คุณก็อยู่ตรงนั้นแล้ว แต่ถ้าไม่เป็นเช่นนั้น Emptyness จะไม่ปฏิบัติตามสัญญา Door ซึ่งโดยปกติหมายความว่าคุณต้องไปอีกทางหนึ่ง

person T.J. Crowder    schedule 17.04.2011

เห็นได้ชัดว่าเราไม่สามารถลดการมองเห็นในการแทนที่วิธีการได้ หากวิธีการปิดประตูบน Door คือ public วิธีการแทนที่ใน Emptyness จะไม่สามารถเป็นแบบส่วนตัวได้...

วิธีการปกติคือการแทนที่เมธอด close door ใน Emptyness และเพียงไม่ทำอะไรเลยหรือโยน UnsupportedOperationException บางส่วนออกไป (เหมือนกับที่ Implementors ของ Iterator do หากพวกเขาไม่อนุญาตให้ลบองค์ประกอบ)

ตัวอย่าง:

 public class Door {
   public void closeDoor() {
     // closing door actions
   }
 }

 public class Emptyness extends Door {
   @Override void closeDoor() {
     // do nothing or
     throw new UnsupportedOperationException("Can't close door on Emptyness");
   }
 }
person Andreas Dolk    schedule 17.04.2011

ทำไมไม่ใช้ Designer Pattern เนื่องจากเมธอด closeDoor นั้นไม่ธรรมดาสำหรับคลาสย่อยทั้งหมดของ Door ดังนั้นจึงไม่ควรมีอยู่ในคลาส Door เลย แทนที่จะสร้างอินเทอร์เฟซที่มีชื่อ Closable ด้วยเมธอด close แล้วใช้อินเทอร์เฟซนั้นในบางคลาส เช่น ClosableTrue และ ClosableFalse ตอนนี้สร้างตัวแปรอ้างอิงในคลาส Door ประเภท Closable และเริ่มต้นในตัวสร้างของคลาสด้วยอ็อบเจ็กต์ ClosableTrue หรือ ClosableFalse ขึ้นอยู่กับประเภทของอาร์กิวเมนต์ที่ส่งไปยังตัวสร้าง ตอนนี้เมื่อใดก็ตามที่มีการเรียกใช้เมธอด close บนอ็อบเจ็กต์ใดๆ ของ Door หรือคลาสย่อยของ Door วิธีการที่ถูกเรียกจะเป็นคลาสที่ใช้เพื่อเริ่มต้น Constructor ของ Door คุณสามารถใช้วิธีการปิดของคลาส ClosableFalse โดยไม่มีฟังก์ชันการทำงานที่มีความหมาย

person Lavneesh    schedule 17.04.2011

ทำให้ ความเป็นส่วนตัวในประตูชั้นเรียน เพราะถ้าคุณมี public หรือ protected ใน super class คุณจะ ไม่สามารถ มีตัวแก้ไขการเข้าถึงที่เข้มงวดกว่านี้ใน ลำดับชั้นด้านล่าง ดังนั้นคุณไม่สามารถสร้างความเป็นส่วนตัวในคลาสว่างได้ แต่ต้องทำในคลาส Door

person GuruKulki    schedule 17.04.2011

มีตัวเลือกมากมาย เลือกสิ่งที่เหมาะกับความต้องการของคุณ

  1. ทำวิธีการ private
  2. สร้างเมธอด final เพื่อไม่ให้ถูกแทนที่และเพิ่มการตรวจสอบลอจิกด้วยว่าเมธอดนี้ได้รับการเรียกจาก instanceof ความว่างเปล่าหรือไม่ จากนั้นจึงส่งข้อยกเว้น

     public class Emptiness extends Door{
    
    
            public static void main(String[] args) throws Exception {
                Door x = new Emptiness();
                x.somemethod();
            }
    
        }
    

    คลาสประตู

    public class Door {         
            final public void somemethod() throws Exception{
                if(this instanceof Emptiness){
                    throw new Exception();
                }
            }
        }
    
person Abhishek    schedule 17.04.2011
comment
จริงๆ แล้ว ฉันไม่ชอบเลย - คลาสไม่ควรใช้งานฟังก์ชันต่างๆ ที่เป็นของคลาสย่อยอย่างชัดเจนและโดยเฉพาะ ในกรณีนี้: ความว่างเปล่าไม่สามารถปิดประตูได้ - person Andreas Dolk; 17.04.2011
comment
ฉันก็เหมือนกัน มันคอมไพล์ แต่ไม่ใช่ OOP ความผิดฉันเอง - person Abhishek; 17.04.2011