سؤال

في جافا، هل هناك أي حالة للسماح بتوسيع فئة غير مجردة؟

يبدو دائمًا أنه يشير إلى وجود تعليمات برمجية سيئة عند وجود تسلسلات هرمية للفئات.هل توافق، ولماذا/لماذا لا؟

هل كانت مفيدة؟

المحلول

وأنا أتفق مع جون وكينت ولكن، مثل سكوت مايرز (في فعالية C ++)، وأنا أذهب أبعد من ذلك بكثير. وأعتقد أن <م> كل فئة يجب أن تكون إما abstract، أو final . وهذا هو، فقط الطبقات ورقة في أي التسلسل الهرمي هي عرضة حقا للمثيل المباشر. جميع الفئات الأخرى (أي العقد الداخلية في الميراث) هي "غير المكتملة"، وينبغي بالتالي أن abstract.

وانها ببساطة لا معنى لفئات المعتادة إلى مزيد من الموسعة. إذا كان الجانب من الدرجة يستحق تمديد و / أو تعديل، فإن الطريقة الأكثر نظافة يتمثل في أن تأخذ فئة واحدة وفصلها إلى الفئة الأساسية abstract واحدة وتنفيذ تبادل واحد ملموس.

نصائح أخرى

هناك بالتأكيد أوقات يكون فيها من المنطقي أن يكون لديك فصول ملموسة غير نهائية.ومع ذلك، فأنا أتفق مع كينت - أعتقد أن الفئات يجب أن تكون نهائية (مختومة في C#) افتراضيًا، وأن أساليب Java يجب أن تكون نهائية افتراضيًا (كما هي الحال في C#).

كما يقول كينت، يتطلب الميراث تصميمًا وتوثيقًا دقيقًا - من السهل جدًا الاعتقاد أنه يمكنك فقط تجاوز طريقة واحدة، ولكن لا تعرف المواقف التي قد يتم فيها استدعاء هذه الطريقة من الفئة الأساسية كجزء من بقية التنفيذ.

يرى "كيف تصمم فئة للميراث" لمزيد من النقاش حول هذا.

وهذا السؤال ينطبق أيضا على المنصات الأخرى مثل C # .NET. هناك من (وأنا منهم) أن نعتقد أن أنواع نهائيا / مختومة من قبل الافتراضي وتحتاج إلى أن تفض صراحة للسماح الميراث.

والإرشاد عن طريق الميراث هو الشيء الذي يحتاج تصميم دقيق وليس بهذه البساطة مجرد ترك نوع تفض. لذلك، أعتقد أنه يجب أن يكون قرار صريح للسماح الميراث.

وهناك أسباب وجيهة للحفاظ على التعليمات البرمجية غير نهائية. العديد من الأطر مثل السبات، الربيع، guice تعتمد في بعض الأحيان على فصول غير النهائية أنها تمتد بشكل حيوي في وقت التشغيل.

وعلى سبيل المثال، السبات يستخدم وكلاء ل كسول جمعية جلب. وخصوصا عندما يتعلق الأمر اوب، هل تريد الخاص بك الطبقات غير نهائية، بحيث اعتراضية يمكن أن نعلق عليه. انظر أيضا السؤال href="https://stackoverflow.com/questions/341624/aop-problem-running-spring-unit-tests">

وأفضل مرجع لديك هنا هو البند 15 من كتاب جوشوا بلوك الممتاز "جافا الفعالة"، ودعا "تصميم وثيقة لالميراث وإلا منعها". ومع ذلك مفتاح ما إذا كان ينبغي السماح تمديد فئة ليست "هو مجردة" ولكن "كان صممت مع الميراث في الاعتبار". هناك في بعض الأحيان وجود علاقة بين الاثنين، إلا أنها ثاني مهم. لنأخذ مثالا بسيطا تم تصميم معظم الطبقات AWT أن تمتد، حتى تلك التي ليست مجردة.

وملخص الفصل بلوخ هو أن التفاعل بين الطبقات الموروثة مع والديهم يمكن أن يكون من المستغرب وunpredicatable إذا لم يكن مصمما الجد لتكون موروثة من. ولذلك ينبغي الطبقات يأتي في نوعين أ) الطبقات مصممة لتكون الموسعة، ومع وثائق كافية لوصف الكيفية التي ينبغي أن يتم ذلك ب) علم على الطبقات النهائية. دروس في الفقرة (أ) وغالبا ما تكون مجردة، ولكن ليس دائما. ل

في بعض الحالات تريد للتأكد من ليس هناك إن شاء subclasses ترث، في الحالات الأخرى التي تريد ضمان شاء subclasses ترث (المجرد). ولكن هناك دائما فرعية واسعة من الطبقات حيث يمكنك كمؤلف الأصلي لا يهمني، وينبغي أن لا يهتمون. انها جزء من الانفتاح / مغلقة. تقرر أن شيئا ما يجب أن تكون مغلقة هو أيضا ينبغي القيام به لسبب ما.

وانا اختلف. إذا كانت التسلسلات الهرمية سيئة، تريد ان تكون هناك أي سبب لوجوه المنحى اللغات في الوجود. اذا نظرتم الى المكتبات القطعة UI من مايكروسوفت والشمس، وكنت متأكدا من العثور على الميراث. هل هذا كل شيء "كود سيئة" حسب التعريف؟ لا، بالطبع لا.

ويمكن أن يساء استخدامها الميراث، ولكن ذلك يمكن لأي ميزة اللغة. هو خدعة لمعرفة كيفية فعل الأشياء بشكل مناسب.

لا أستطيع أن أختلف أكثر.تكون التسلسلات الهرمية للفئات منطقية بالنسبة للفئات المحددة عندما تعرف الفئات المحددة أنواع الإرجاع المحتملة للطرق التي لم تضع عليها علامة نهائية.على سبيل المثال، فئة محددة قد يكون لها ربط فئة فرعية:

protected SomeType doSomething() {
return null;
}

يتم ضمان أن يكون doSomething هذا خاليًا أو مثيل SomeType.لنفترض أن لديك القدرة على معالجة مثيل SomeType ولكن ليس لديك حالة استخدام لاستخدام مثيل SomeType في الفصل الحالي، ولكن اعلم أن هذه الوظيفة ستكون جيدة حقًا في الفئات الفرعية وأن معظم كل شيء ملموس.ليس من المنطقي جعل الفئة الحالية فئة مجردة إذا كان من الممكن استخدامها مباشرة مع عدم القيام بأي شيء بقيمتها الخالية.إذا جعلتها فئة مجردة، فسيكون لديك أطفالها في هذا النوع من التسلسل الهرمي:

  • مجردة الطبقة الأساسية
    • الفئة الافتراضية (الفئة التي كان من الممكن أن تكون غير مجردة، وتنفذ فقط الطريقة المحمية ولا شيء آخر)
    • فئات فرعية أخرى.

وبالتالي، لديك فئة أساسية مجردة لا يمكن استخدامها مباشرة، عندما تكون الفئة الافتراضية هي الحالة الأكثر شيوعًا.في التسلسل الهرمي الآخر، هناك فئة واحدة أقل، بحيث يمكن استخدام الوظيفة دون إنشاء فئة افتراضية عديمة الفائدة بشكل أساسي لأنه يجب فرض التجريد على الفصل.

  • الطبقة الافتراضية
    • فئات فرعية أخرى.

الآن، بالتأكيد، يمكن استخدام التسلسلات الهرمية وإساءة استخدامها، وإذا لم يتم توثيق الأشياء بشكل واضح أو لم يتم تصميم الفئات بشكل جيد، يمكن أن تواجه الفئات الفرعية مشاكل.ولكن هذه المشاكل نفسها موجودة أيضًا مع الفصول المجردة، فلن تتخلص من المشكلة بمجرد إضافة "ملخص" إلى فصلك.على سبيل المثال، إذا كان عقد طريقة "doSomething()" أعلاه يتطلب من SomeType ملء حقول x وy وz عند الوصول إليها عبر الحروف والمحددات، فسوف تنفجر فئتك الفرعية بغض النظر عما إذا كنت تستخدم الفئة المحددة التي أرجعت فارغة كفئة أساسية أو فئة مجردة.

القاعدة العامة لتصميم التسلسل الهرمي للفصل هي إلى حد كبير استبيان بسيط:

  1. هل أحتاج إلى سلوك الطبقة الفائقة المقترحة في فئتي الفرعية؟(ص/ن) هذا هو السؤال الأول الذي تحتاج إلى طرحه على نفسك.إذا لم تكن بحاجة إلى هذا السلوك، فليس هناك حجة للتصنيف الفرعي.

  2. هل أحتاج إلى حالة الطبقة الفائقة المقترحة في فئتي الفرعية؟(ص/ن) هذا هو السؤال الثاني.إذا كانت الولاية تناسب نموذج ما تحتاجه، فقد يكون هذا مرشحًا للفئة الفرعية.

  3. إذا تم إنشاء الفئة الفرعية من الفئة الفائقة المقترحة، فهل ستكون حقًا علاقة IS-A، أم أنها مجرد اختصار لوراثة السلوك والحالة؟هذا هو السؤال الأخير.إذا كان مجرد اختصار ولا يمكنك تأهيل الفئة الفرعية المقترحة "كـ-a"، فيجب تجنب الوراثة.يمكن نسخ الحالة والمنطق ولصقهما في الفئة الجديدة بجذر مختلف، أو يمكن استخدام التفويض.

فقط إذا كانت الفئة تحتاج إلى السلوك، فيمكن اعتبار أن مثيل الفئة الفرعية IS-A(n) للفئة الفائقة يجب اعتباره وراثة من فئة فائقة.بخلاف ذلك، توجد خيارات أخرى قد تكون أكثر ملاءمة لهذا الغرض، على الرغم من أنها قد تتطلب المزيد من العمل مقدمًا، إلا أنها أكثر نظافة على المدى الطويل.

وهناك عدد قليل من الحالات التي نحن لا ترغب في السماح لتغيير السلوك. على سبيل المثال، فئة سلسلة الرياضيات.

وأنا لا أحب الميراث لأن هناك دائما طريقة أفضل للقيام بنفس الشيء ولكن عندما كنت بصدد إجراء تغييرات الصيانة في نظام ضخم أحيانا أفضل طريقة لإصلاح الرمز مع الحد الأدنى من التغييرات هو تمديد فئة قليلا . نعم، انها عادة ما يؤدي إلى رمز سيئة ولكن لعمل واحد وبدون أشهر من إعادة كتابة أولا. لذلك إعطاء رجل أعمال الصيانة بقدر من المرونة كما كان يمكن التعامل معها هو وسيلة جيدة للذهاب.

scroll top