Әртүрлі нысандар үшін бірнеше мәрте тексерулерге тең болуы мүмкін бе?

Менде әртүрлі объектілердің түрлерін тексеретін бір сынып бар деймін. equals() дегенді келесі жолмен елемеуге болады ма/мүмкін бе?

public boolean equals(Object o){
    if(o == null) return false;
    if(o instanceof class1){
        return this.class1.equals((class1) o);
    if(o instanceof class2){
        return this.class2.equals((class2) o);
    ...

}

Бұл пайдалы болар ма еді? Мен мұнда тиісті сыныптарда статикалық шамадан тыс жүктелген equals() әдісін жасауды болжай аламын (бірақ полиморфизм автоматты түрде бұл туралы қамқорлық жасайтын болса).

1
Сондай-ақ, қараңыз: stackoverflow.com/questions/596462/…
қосылды автор Raedwald, көзі
Бұл код заңды болып табылады, сондықтан мүмкін. Бірақ бір сыныпта болса, екі нысан тең болады деп айту дұрыс емес. Егер сіз осындай эксперимент жүргізуді қаласаңыз, ОО-да оны орындаудың дұрыс әдісі әрбір кіші сыныбында теңдестіруге болады.
қосылды автор Mister Smith, көзі
Сіздің тамаша пікірлеріңізге рахмет.
қосылды автор user991710, көзі
@CedricMartin Сіз шынымен емес. Теңшелімді өзгертетін субкласстарға атрибуттарды қосу мүмкін емес. Ал, тіпті бұрынғы сөйлем де дұрыс емес: Сіз теңдікті теңестіре аласыз (яғни, теңдік қатынасының кепілдік берілген математикалық қасиеттерінің ешқайсысын бұзбайсыз), тіпті, бұл жай ғана әдетте ешкімге қажет емес, демек практикалық құндылығы аз. Шын мәнінде, остерски мұны қалай жасау керектігін көрсететін мақаланы жазды. Өңдеу: Немесе жай ғана подкласса дұрыс енгізілгеніне кепілдік бере алмайсыз ба? Рас, бірақ сол кезде мен айтқан көптеген нәрселер үшін де солай.
қосылды автор Voo, көзі
@CedricMartin Odersky әлі күнге дейін тең, бірақ көмекші әдіспен қолданылады. Әрине, мінез-құлқымды өзгертпейтін және жақсы жұмыс жасайтын ішкі сыныптар жаздым. Мен тіпті атрибуттар енгізген және ата-аналармен салыстырғанда теңдесі жоқ әрқайсысын бағалайтын сыныптарда жақсы болған жағдайлар. Бірақ сіз негізгі проблеманы қалай шешесіз? Мен супермагистральды салыстыра отырып, сол проблемаларды жай ғана көтеріп жатқанда, теңдестіретін орынды қалайша маңызды екенін көрмеймін. Ұсынылған шешім қандай болады?
қосылды автор Voo, көзі
@CedricMartin Жоқ, жоқ емес транзитивтілігін бұзады, әр математикалық қасиет тең қатынаста болу керек. Иә, біз қосымша әдіс қажет болса, онда біз тең деп жазыңыз, иә, міндетті түрде интуитивті емес - және? Егер сіздің шешіміңіз «Жақсы ғана теңдіктерді пайдаланбаңыз» - менің ойымша, мен ештеңені қолданбаудың орнына «керемет шешімді» өткіземін деп ойлаймын. Нақты ООП жерінде хэшмэз, тапсырыс жинақтарынсыз және екі әдіс қажет болатын кез келген жерде бағдарламалау қызықты болуы керек. Мен практикалық шешімді жақсы көремін деп ойлаймын.
қосылды автор Voo, көзі
ол сіз істеп жатқаныңызға байланысты «пайдалы» болуы мүмкін, бірақ Java иерархиясының жоғарғы жағында тең және hashCode екенін білу керек. Онда ешқандай жол жоқ. Сіз мұраға ие болған кезде тең/hashcode келісімдеріне кепілдік бере алмайсыз. Осындай қарапайым. мүмкін емес . Effective Java ішіндегі Джошуа Блохтың бұл жағымды және өте анық және түсіндірмейтін түсіндірмесі. Сондай-ақ, Артимада бұл тақырып бойынша Мартин Одерскийдің (Scala даңқынан) тамаша сұхбаты бар.
қосылды автор Cedric Martin, көзі
@Voo: Одесский бұл мәселені шешу үшін бір күнді көрсететін мақаланы жазды, equals() және hashCode() пайдаланбай (ол басқа әдістерді жасайды). Джошуа Блох бұл туралы былай деді: «Шартты кеңейтіп, тең шартты сақтау кезінде аспектті қосудың жай мүмкіндігі жоқ» . Мен мұрагерімді пайдаланғыңыз келсе (ол, әдетте, сыныптар мен кіші класстар болуы керек), OO иерархиясының жоғарғы жағында тең және hashCode Java-де сынған. Мәселені шешкен жоқпын: Мен тең және hashCode екенін айтқым келеді.
қосылды автор Cedric Martin, көзі
@Voo: Енді, егер сіз ОО жасамасаңыз, мысалы, егер сіз Java-ді процедуралық жолмен пайдалансаңыз және әрқашан бірдей объектілерді коллекцияға қойсаңыз, онда теңеледі және hashCode жұмыс істейді:) Сондықтан «төменгі сыныптар үшін аспект/атрибуттар қосылмасаңыз, » болады, бірақ біз шын мәнінде мұраға және OO !!
қосылды автор Cedric Martin, көзі
@Voo: «Тіпті атрибуттар қосқан және тіпті әрқашан тең емес бағалау сыныбы бар жақсы жағдайлар» , бірақ кейін сіз өтімділікті бұзды ( Effective Java ). Сонымен, бұл толық шеңберді, мен тағы да дәл айтқым келеді, Джошуа Блхш тиімді Java-те жазған: «Шартты сыныпты кеңейту және тең шартты сақтай отырып, аспектті қосудың жай мүмкіндігі жоқ» . Сіз Joshua Bloch-пен өзіңіз қалағандай келісе аласыз: сіз келісім шартты бұзғансыз . Ұсынылған шешім? сәйкесінше және hashCode сынғанын білдіріп, оларды пайдалануды тоқтатыңыз немесе OO әрекетін жасамаңыз деп тоқтаңыз.
қосылды автор Cedric Martin, көзі
@Voo: Сіз Одерскің айтуынша, оның шешімі мінсіз емес (және ол көмекші әдіс арқылы жасалмайды, ол әдіс арқылы жасалады, ол барлық объектілерде әр жерде тең және hashCode қатысады ). Енді тоқтаңыз!
қосылды автор Cedric Martin, көзі

4 жауаптар

I very much doubt that because you can easily violate the transitivity of equals this way (x.equals(y) && x.equals(z) implies y.equals(z))

Әрине, сіз барлық сыныптарда орнатуды өте көп жасайсыз, бірақ бұл дұрыс бола алмайды

3
қосылды
Өте нашар Мен бірнеше жауап ала алмаймын!
қосылды автор user991710, көзі

Белгіленген нысанның кемінде бір қабылдағыштағы әртүрлі мүше айнымалыларына тең екендігін тексеру әдісі қажет сияқты.

java.lang.Object # equals .

Оның орнына басқа әдіс, мысалы:

public boolean hasEquals(Object o) {//your impl }
1
қосылды

Семантикалық тұрғыда бұл жақсы идея емес деп ойлаймын. Теңдік сынып түрлеріне негізделмеуі керек, бірақ дана айнымалылары. Сонымен қатар, Apple алмұртқа ешқашан тең болмауы керек, тек басқа алма.

1
қосылды

Егер сіз өзара регулярияға алып келмейтініне сенімді болсаңыз, that.equals (this) -ті қайтаруға болады. Алайда, жалпы алғанда, объект теңдігі сыныптардың теңдігі немесе кем дегенде олардың арасындағы мұрагерлік мұра болып табылады.

0
қосылды