متغيرات مثيل "التجويد" في النوع الفرعي: المخاطر المحتملة؟

StackOverflow https://stackoverflow.com/questions/2864595

سؤال

لنفترض أن لدي فئة فائقة فئة وفئة فرعية فرعية ودرك فرعي يرثون من الفئة الفائقة.

 abstract class SuperClass{
   ...
   List someList;
   ...
 }

 class SubClassA extends SuperClass{
   ...
   List<String> someList;
   ...
 }

 class SubClassB extends SuperClass{
   ...
   List<Integer> someList;
   ...
 }

وبهذه الطريقة يكون ذلك مناسبًا لأنني أستطيع الحصول عليها someList.size() في Superclass ولديها نوعية في الفئات الفرعية. المشكلة هي أنه لا "يشعر" بشكل صحيح ، هل يمكنك التفكير في المخاطر المحتملة التي لدى Apporach التي لا أعرفها؟

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

المحلول

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

أستطيع الحصول على someList.size() في Superclass

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

السبب وراء ذلك هو ذلك SubClassA.someList لا يحل محل أو تجاوز بأي شكل من الأشكال Superclass.someList - إنها مجرد ظلال ، هكذا ترى أساليب الفئة الفرعية SubClassA.someList بدلاً من Superclass.someList. ومع ذلك ، هذا ليس له أي تأثير على الإطلاق في Superclass. يمكن جعل الطرق افتراضية (وفي Java ، فهي بشكل افتراضي) ، لكن أعضاء البيانات لا يمكنهم ذلك.

نصائح أخرى

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

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

استبدال المتغير بالطريقة التي أقترحها.

شكرًا.

يبدو أنه يكسر IS-A ومبدأ استبدال Liskov بالنسبة لي. إذا كان لديك مجموعة من مثيلات الفئة الفائقة ، يمكن أن يكون كل منها فئة فرعية أو فئة فرعية ، فستحصل على بعض السلوك المثير للدهشة في أحسن الأحوال.

لا تفعل ذلك.

ربما يكون شيء ما يستخدم الأدوية أفضل:

public class X<T>
{
    private List<T> list;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top