سؤال

ولدي مجموعة من الطبقة يقومون بتنفيذ واجهة مشتركة: الأوامر.

وهذه باقة من الدرجة يذهب إلى خريطة.

لتحصل على خريطة العمل بشكل صحيح، ولست بحاجة إلى كل فئة الذين ينفذ الأوامر لتجاوز أسلوب Object.equals(Object other).

وأنه بخير.

ولكن أنا whould تريد فرض الطاغية على قدم المساواة. => هل لديك خطأ في تجميع عندما يكون هناك شيء من تنفيذ أمر لا أميل تجاوز يساوي.

ومن ذلك ممكن؟

وتحرير: راجع للشغل، وأنا سوف تحتاج أيضا إلى إجبار تجاوز شفرة التجزئة ...

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

المحلول

لا، لا يمكنك. ما يمكنك القيام به، ومع ذلك، يتم استخدام الفئة الأساسية مجردة بدلا من واجهة، وجعل equals() مجردة:

abstract class Command {
   // put other methods from Command interface here

   public abstract boolean equals(Object other);
   public abstract int hashCode();
}

والفئات الفرعية من Command <م> يجب ثم توفير متساوين الخاصة بها وطرق شفرة التجزئة.

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

نصائح أخرى

ويمكن أن تمتد الأشياء الخاصة بك من XObject المجرد بدلا من java.lang.Object؟

public abstract class XObject
 extends Object
{
@Override
public abstract boolean equals(Object o);
}

وسوف فئات مجردة لا تعمل إذا كان لديك حفيد منذ الده overrided بالفعل كلا متساوين وطرق شفرة التجزئة ومن ثم كان لديك مشكلة كل ما تبذلونه من جديد.

وحاول استخدام annotatins وAPT ( HTTP: // docs.oracle.com/javase/1.5.0/docs/guide/apt/GettingStarted.html ) للحصول عليها القيام به.

وهذا من شأنه أن يكون ممكنا إلا إذا كان القيادة واجهة أو فئة مجردة، حيث يساوي (..) هو أسلوب أعلن ومجردة.

والمشكلة هي أن كائن، وهو الفائقة لكافة الكائنات، يعرف بالفعل هذا الأسلوب.

إذا كنت ترغب تشير إلى أن هذه مشكلة (في وقت التشغيل)، هل يمكن رمي استثناء، لإجبار مستخدمي API لتجاوزه. ولكن ليس من الممكن في وقت الترجمة، على الأقل على حد علمي.

وحاول العمل حوله، من خلال وجود وسيلة API محددة، على سبيل المثال، CommandEquals. الخيار الآخر هو (كما ذكر) توسيع فئة أخرى الذي يعرف يساوي طريقة مجردة.

يمكنك إنشاء boolean myEquals() في interface Command، وإنشاء محول مثل هذا:

class MyAdapter{
  Command c;
  boolean equals(Object x) {
    return c.myEquals((Command)x);
  }
}

وبعد ذلك يمكنك فقط استخدام map.put(key, new MyAdapter(command)) بدلا من map.put(key, command)

وكذلك إذا كنت ترغب في وقت تحقق يمكنك أن تفعل شيئا مثل:

    interface Foo{

}
class A implements Foo {

}
class B implements Foo {
    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }
}

public static void main(String[] args) {
    Class<A> clazzA = A.class;
    Class<B> clazzB = B.class;

    Class<Object> objectClass = Object.class;
    try {
        Method methodFromObject = objectClass.getMethod("equals",Object.class);
        Method methodFromA = clazzA.getMethod("equals",Object.class);
        Method methodFromB = clazzB.getMethod("equals",Object.class);
        System.out.println("Object == A" + methodFromObject.equals(methodFromA));
        System.out.println("Object == B" + methodFromObject.equals(methodFromB));
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
}

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

interface A{
    public boolean equal2(Object obj);
}

abstract class B implements A {

    @Override
    public boolean equals(Object obj) {
        return equal2(obj);
    }

}


class C extends B {

    public boolean equal2(Object obj) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

ومنذ يورث equals() من Object أشك في أنك لا تستطيع أن تجبر حقا أنه منذ ل<م> كل اكتب هناك تنفيذ الموروثة التلقائي للequals() المتاحة.

وأنا لا أعتقد أنه من الممكن أن تجبر الغلابة على قدم المساواة لانها تأتي من فئة كائن.

وعلى صعيد ذات صلة، لاحظ أن تحتاج إلى تجاوز أسلوب "شفرة التجزئة" من فئة كائن أي وقت مضى عندما تجاوز متساوين. هذا يصبح من المهم اسبيكالي إذا كنت تسير على استخدام مثيلات من الفصول الدراسية كمفاتيح للخريطة. تحقق هذا المقال: http://www.artima.com/lejava/articles/equality.html الذي يقدم بعض النصائح حول كيفية تجاوز يساوي بطريقة صحيحة

وأما الإجابات الأخرى قد أوضح بالفعل، لا يمكنك يتم فرض نوع من الاشياء التي تحاول.

والشيء الوحيد الذي يمكن أن تعمل "كفى" هو تحديد واجهة الثانية، نسمي هذا MappableCommand واحد.

public interface MappableCommand 
{

}

في وثائق لهذه الواجهة تشير إلى أن فئة ينبغي أن تنفذ هذا فقط (فارغ) واجهة إذا كان مصمم الطبقة نظرت متطلبات ذكرتم.

وبعد ذلك يمكنك تعيين نوع قيمة خريطتك لMappableCommand، وفقط MappableCommands سوف تكون قادرة على أن تضاف إلى الخريطة.

وهذا هو مماثل لمنطق وراء لماذا يحتاج المرء لتنفيذ (فارغة) واجهة للتسلسل لالفئات التي يمكن إجراء تسلسل آليات التسلسل الافتراضي جاوة.

إذا لم يفلح ذلك، ثم قد تضطر إلى تسوية لرمي خطأ وقت التشغيل؛

وتحرير وهمية:

إذا أردت جعل هذا المطلب أكثر وضوحا هل يمكن تحديد واجهة جديدة بهذه الطريقة

public interface MappableCommand 
{

    public void iOverrodeTheEqualsMethod();

    public void seriouslyIPromiseThatIOverrodeIt();

}

وهنا الاختلاف من بعض الحلول المقترحة الأخرى:

public abstract class CommandOverridingEquals implements Command {
    public abstract boolean equals(Object other);
    public abstract int hashcode();
}

Map<String, CommandOverridingEquals> map = 
    new HashMap<String, CommandOverridingEquals>();

وأو إذا كنت تريد حقا أن تكون على يقين، واستخدام hashmap فحص. منها مثلا.

Map<String, CommandOverridingEquals> map = Collections.checkedMap(
    new HashMap<String, Command>(),
    String.class, CommandOverridingEquals.class);

ولكن بغض النظر عن ما تفعله لا يمكن إيقاف شخص القيام بذلك:

public class AntiFascistCommand extends CommandOverridingEquals {
    public boolean equals(Object other) { return super.equals(other); }
    public int hashcode() { return super.hashcode(); }
    ...
}

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

والمنظمة البحرية الدولية، انها فكرة سيئة في محاولة لاجبار المطور في نمط التنفيذ معين. سيكون من الأفضل لوضع بعض التحذيرات القوية في Javadocs والاعتماد على المطورين ل<م> فعل الشيء الصحيح .

هل من الممكن بالنسبة لك لتوفير java.util.comparator الخاصة بك إلى الخريطة في السؤال؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top