Java'nın @Override ek açıklamasını ne zaman kullanırsınız ve neden?


498

Java'nın @Overrideek açıklamasını kullanmak için en iyi uygulamalar nelerdir ve neden?

Geçersiz kılınan her bir yöntemi @Overrideek açıklama ile işaretlemek aşırıya kaçmış gibi görünüyor . Kullanmayı gerektiren @Overrideve asla kullanmaması gereken bazı programlama durumları var @Overridemı?

Yanıtlar:


515

İki avantaj için bir yöntemi her geçersiz kıldığınızda kullanın. Bunu yaptığınızda, derleyici denetiminden yararlanabileceğinizi düşündüğünüzde bir yöntemi geçersiz kıldığınızdan emin olun. Bu şekilde, bir yöntem adının yanlış yazılması veya parametrelerin doğru eşleştirilmemesi gibi yaygın bir hata yaparsanız, yönteminizin düşündüğünüz gibi geçersiz kılmadığı konusunda uyarılırsınız. İkinci olarak, kodların anlaşılmasını kolaylaştırır, çünkü yöntemlerin üzerine yazıldığında daha açıktır.

Ayrıca, Java 1.6'da, bir yöntemin aynı yararlar için bir arabirim uyguladığında işaretlemek için kullanabilirsiniz. Ayrı bir ek açıklama (örneğin @Implements) almanın daha iyi olacağını düşünüyorum , ancak hiçbir şeyden daha iyi.


4
"Anlaşılması daha kolay" ile aynı satırlar boyunca, IDE'ler @Override ek açıklamasını tespit eder ve editördeki geçersiz kılma yöntemini görsel olarak işaretler.
Bob Cross

47
Bazı IDE'ler, @Override ek açıklamasını da içermeyen geçersiz kılınmış bir yöntemi işaretler.
Jay R.

20
Diğer bir avantaj, üst sınıf değişirse, derleyici alt sınıfların da güncellendiğinden emin olacaktır.
David

4
@Jay R .: Doğru. Nitekim, örneğin Eclipse, eksikse @Override'ı otomatik olarak ekleyebilir.
sleske

32
Arayüzlerden gelen yöntemlerde @Overrides için görünüşte belgelenmemiş değişiklik nedeniyle başka birinin buraya gelmesi durumunda, bugs.sun.com/bugdatabase/view_bug.do?bug_id=5008260 ilgili hata gibi görünüyor. (İşaret ettiğiniz için teşekkürler, Dave L.!)
Henrik Heimbuerger

110

Derleme zamanı hatırlatma olarak en yararlı olduğunu düşünüyorum yöntemin amacı bir üst yöntemi geçersiz kılmaktır. Örnek olarak:

protected boolean displaySensitiveInformation() {
  return false;
}

Genellikle, temel sınıftaki bir yöntemi geçersiz kılan yukarıdaki yöntem gibi bir şey görürsünüz. Bu, bu sınıfın önemli bir uygulama detayıdır - hassas bilgilerin görüntülenmesini istemiyoruz.

Bu yöntemin üst sınıfta şu şekilde değiştirildiğini varsayalım:

protected boolean displaySensitiveInformation(Context context) {
  return true;
}

Bu değişiklik derleme zamanı hatalarına veya uyarılarına neden olmaz - ancak alt sınıfın amaçlanan davranışını tamamen değiştirir.

Sorunuzu cevaplamak için: Üst sınıfta aynı imzalı bir yöntemin olmaması bir hatayı gösteriyorsa @Override ek açıklamasını kullanmalısınız.


46

Burada çok iyi cevaplar var, bu yüzden bakmanın başka bir yolunu sunayım ...

Kodlama sırasında aşırıya kaçma yoktur. @Override yazmak için herhangi bir ücret ödemezsiniz, ancak bir yöntem adını yanlış yazdıysanız veya imzayı biraz yanlış yaptıysanız tasarruf çok büyük olabilir.

Şöyle düşünün: Buraya gittiğinizde ve bu gönderiyi yazdığınızda, hayatınızın geri kalanında @override yazarak geçireceğiniz zamandan çok daha fazla zaman kullandınız; ancak önlediği bir hata size zaman kazandırabilir.

Java, düzenleme / derleme zamanında herhangi bir hata yapmadığınızdan emin olmak için elinden geleni yapar, bu, kapsamlı testlerin dışında herhangi bir şekilde önlenemeyen bir hata sınıfının tamamını çözmenin neredeyse ücretsiz bir yoludur.

Kullanıcı bir yöntemi geçersiz kılmayı amaçladığında, aslında yaptığını sağlamak için Java'da daha iyi bir mekanizma bulabilir misiniz?

Başka bir düzgün etki, ek açıklamayı sağlamazsanız, derhal bir ana yöntemi geçersiz kıldığınızda sizi uyarır - bunu yapmak istemezseniz önemli olabilecek bir şeydir.


3
"Kod yazarken aşırıya kaçmak yok." Buna katılıyorum, bu yüzden dinamik şeritleri çok yanlış buluyorum (ücretli çalışmamın% 100'ü şu anda yakutta olsa da).
Dan Rosenstark

4
+1: Belki de geçersiz kılmadaki bir hata nedeniyle 10 hata aldım - bunlardan herhangi birini bulmak için gereken süre, geçersiz kılma yöntemlerimin her birinde @Override yazma süresini kolayca aşmış olurdu. Ayrıca, @Override biraz külfetli ise, büyük olasılıkla aşırı miras alıyorsunuz demektir.
Lawrence Dol

7
Çok gerçek bir dezavantajı, kodu salyangozlarla çökerek okumayı zorlaştırmanızdır. Belki de IDE'mın bir hatası, ama bunu kendim yaşadım.
Modlarınızı iyi tedavi edin

9
@ phyzome Eğer "Salyangoz" hantal bulursanız, YAKIN YERDE yeterli yorum kullanmıyorsunuz. Onlar sadece iyi bir vurgulu metin ve javadocs sağlamak için çoğu durumda (birkaç satır) yönteminiz kadar büyük olması gereken yöntem başlığının üzerinde tek bir satır olmalıdır. Sanırım sorunun Salyangoz olmadığını, okuma alışkanlıklarınız olduğunu söylüyorum. Koddaki tüm bu parantezler de sizi rahatsız ediyor mu?
Bill K

4
Evet, kodlamada aşırıya kaçma var: kodun açıkça ne yaptığını papağan yapan yorumlar yazdığınızda.
Karıncalar

22

Her zaman etiketi kullanırım. Yapabileceğim küçük hataları yakalamak basit bir derleme zamanı bayrağı.

Bunun tostring()yerinetoString()

Küçük şeyler büyük projelerde yardımcı olur.


18

@OverrideEk açıklamayı kullanmak, ortak bir programlama hatasına karşı derleme zamanı koruması görevi görür. Üst sınıf yöntemini geçersiz kılmadığınız bir yönteme ilişkin ek açıklama varsa derleme hatası verir.

Bunun yararlı olduğu en yaygın durum, temel sınıftaki bir yöntemi farklı bir parametre listesine sahip olacak şekilde değiştirmektir. Üst sınıf yöntemini geçersiz kılmak için kullanılan bir alt sınıftaki yöntem, değiştirilen yöntem imzası nedeniyle artık bunu yapmayacaktır. Bu bazen, özellikle karmaşık kalıtım yapılarıyla uğraşırken garip ve beklenmedik davranışlara neden olabilir. @OverrideBuna karşı ek açıklama önlemler.


En iyi cevap. Kısa ve güzel. Keşke "koruma" nasıl çalışır açıklamak isterdim .... kimse bunu açıkladı.
djangofan

Açıklamak kolaydır. Bir hata yaparsanız (arabirimi, soyut sınıfı veya alt sınıfı değiştirerek) bir uyarı (Eclipse'de olduğu gibi) veya @Override'ınızın çalışmadığını bildiren bir derleme zamanı hatası alırsınız. mesaj neyin değiştiğine bağlı olacaktır, ancak Eclipse'de (örneğin) bir sorun olduğu çok hızlı bir şekilde açıktır: küçük kırmızı zikzakın altını çizeceksiniz ve rahatsız edici metnin üzerine geldiğinizde neyin yanlış olduğunu söyleyeceksiniz. Buna İyi Değer diyorum
Ichiro Furusato

14

Derleyici denetiminden yararlanmak için her zaman Geçersiz Kılma ek açıklamasını kullanmalısınız. Ancak, Java Compiler 1.5'in arayüz yöntemlerini geçersiz kılarken bu ek açıklamaya izin vermeyeceğini unutmayın. Sadece sınıf yöntemlerini geçersiz kılmak için kullanabilirsiniz (soyut veya değil).

Eclipse olarak Java ID çalışma zamanı veya daha üstü ile yapılandırılmış bazı IDE'ler, Java 1.5 ile uyumluluğu korurlar ve @override kullanımına yukarıda açıklandığı gibi izin vermezler. Bu davranışı önlemek için aşağıdakilere gitmelisiniz: Proje Özellikleri -> Java Derleyici -> “Projeye Özgü Ayarları Etkinleştir” -> “Derleyici Uyumluluk Düzeyi” = 6.0 veya üstünü seçin.

Tabanın bir arabirim veya sınıf olması durumunda, bağımsız olarak bir yöntemi geçersiz kıldığımda bu ek açıklamayı kullanmayı seviyorum.

Bu, bir olay işleyiciyi geçersiz kıldığınızı ve daha sonra hiçbir şey görmediğinizi düşündüğünüz gibi bazı tipik hatalardan kaçınmanıza yardımcı olur. Bazı kullanıcı arayüzü bileşenlerine bir olay dinleyicisi eklemek istediğinizi düşünün:

someUIComponent.addMouseListener(new MouseAdapter(){
  public void mouseEntered() {
     ...do something...
  }
});

Yukarıdaki kod derlenir ve çalıştırılır, ancak fareyi someUIComponent içinde hareket ettirirseniz “bir şeyler yap” kodu çalıştırmayı not eder, çünkü aslında temel yöntemi geçersiz kılmazsınız mouseEntered(MouseEvent ev). Sadece yeni bir parametresiz yöntem oluşturursunuz mouseEntered(). Bu kod yerine, @Overrideek açıklamayı kullandıysanız derleme hatası gördünüz ve olay işleyicinizin neden çalışmadığını düşünmek için zaman kaybetmediniz.


8

@Java'da "bir arabirimi geçersiz kılma" diye bir şey olmadığından, arabirim uygulamasında geçersiz kılma tutarsız.

@ Arayüz uygulamasında aşırı yükleme işe yaramaz çünkü uygulamada derlemenin yine de yakalayamayacağı hiçbir hata yakalamaz. Uygulayıcılarda geçersiz kılma işleminin gerçekte bir şey yaptığı tek, çok getirilen bir senaryo vardır: Bir arabirim uygularsanız ve arabirim REMOVES yöntemlerini kullanırsanız, kullanılmayan uygulamaları kaldırmanız gerektiğinde derleme zamanında size bildirilir. Arayüzün yeni sürümü YENİ veya DEĞİŞTİRİLMİŞ yöntemlere sahipse, yeni öğeleri uygulamadığınız için zaten derleme hatası alacağınıza dikkat edin.

@ Arabirim uygulayıcıları üzerinde aşırı yüklemeye 1.6'da izin verilmemeliydi ve eklenti ne yazık ki ek açıklamaları varsayılan davranış olarak otomatik olarak eklemeyi seçtiğinde, çok fazla dağınık kaynak dosyası alıyoruz. 1.6 kodunu okurken, bir yöntem üst sınıftaki bir yöntemi gerçekten geçersiz kılarsa veya yalnızca bir arabirim uygularsa @Override ek açıklamasından göremezsiniz.

Bir üst sınıftaki bir yöntemi geçersiz kılarken @Override kullanmak iyidir.


2
Bu konuda farklı görüşler var. Bkz. Stackoverflow.com/questions/212614/… .
sleske

8

Geçersiz kılmayı amaçlayan her yöntem ve Java 6+, bir arabirimin uygulanması olarak tasarlanan her yöntem için kullanmak en iyisidir.

Birincisi, derleme zamanında " hashcode()" yerine " " gibi yazım hatalarını yakalar hashCode(). Gerçek neden, kodunuzun asla çağrılmaması durumunda, yönteminizin sonucunun neden kodunuzla eşleşmediğini hata ayıklamak şaşırtıcı olabilir.

Ayrıca, bir üst sınıf bir yöntem imzasını değiştirirse, eski imzanın geçersiz kılmaları "öksüz bırakılabilir", arkada kafa karıştırıcı ölü kod olarak bırakılabilir. @OverrideAçıklama yeni imzayı uyumlu olacak şekilde değiştirilmesi, böylece bu yetim belirlemenize yardımcı olacaktır.


7

Kendinizi çok sık kullanılan (soyut olmayan) yöntemleri çok sık buluyorsanız, muhtemelen tasarımınıza bakmak istersiniz. Derleyici başka türlü hatayı yakalamadığında çok kullanışlıdır. Örneğin, ThreadLocal'da yaptığım initValue () işlevini geçersiz kılmaya çalışıyorum.

Arayüz yöntemlerini (1.6+ özellik) uygularken @Override kullanmak benim için biraz abartılı görünüyor. Bazıları geçersiz kılan ve bazıları yapmayan bir sürü yönteminiz varsa, muhtemelen muhtemelen kötü tasarım (ve editörünüz muhtemelen hangisini bilmiyorsanız gösterecektir).


2
Aslında, geçersiz kılınan arayüz yöntemleri için de güzel. Örneğin, eski, kullanımdan kaldırılmış bir yöntemi bir arabirimden kaldırırsam, bu yöntem tüm uygulayıcı sınıflardan da kaldırılmalıdır - @override kullanıyorlarsa bunları tespit etmek kolaydır.
Dominik Sandjaja

7

Arayüzlerde aşırı yükleme aslında faydalıdır, çünkü arayüzü değiştirirseniz uyarılar alırsınız.


7

Yaptığı başka bir şey, kodu okurken üst sınıfın davranışını değiştirdiğini daha açık hale getirmesidir. Hata ayıklamada yardımcı olabilir.

Ayrıca, Joshua Block'un Etkili Java (2. baskı) kitabında, madde 36 ek açıklamanın avantajları hakkında daha fazla ayrıntı verir.


Evet, gerçekten - madde 36 :)
Chris Kimpton

6

Bir arayüz yöntemi uygularken @Override kullanmak kesinlikle mantıklı değildir. Bu durumda kullanmanın bir avantajı yoktur - derleyici hatalarınızı zaten yakalayacaktır, bu yüzden sadece gereksiz dağınıklıktır.


6
@OverrideBir arabirimde kullanmak , arabirimdeki bir yöntemin ne zaman kaldırıldığını fark etmeye zorlar.
Alex B

@Alex: Bir arabirimdeki yöntemlerin kaldırılması, ekleme gibi bir değişikliktir. Bir arayüz yayınlandıktan sonra, onu kullanan tüm kodlar üzerinde tam kontrole sahip olmadığınız sürece etkili bir şekilde kilitlenir.
Lawrence Dol

6

Bir yöntem başka bir yöntemi geçersiz kıldığında veya bir yöntem bir arabirimde imza uygular.

@OverrideEk açıklama aslında geçersiz kılma şey yaptığını size garanti eder. Ek açıklama olmadan, yanlış yazım veya parametre türlerinde ve sayısında bir fark riskiyle karşı karşıya kalırsınız.


1
Yalnızca Java 1.6
Dave L.'de

5

Her seferinde kullanıyorum. Bir yıl içinde kodu tekrar ziyaret ettiğimde ne olduğunu hızlı bir şekilde anlamak için kullanabileceğim daha fazla bilgi ve ilk kez ne düşündüğümü unuttum.


5

En iyi pratik her zaman kullanmaktır (veya IDE'nin sizin için doldurmasını sağlamaktır)

@ Override yararlılığı, hiyerarşide bildirilmeyen üst sınıflardaki değişiklikleri algılamaktır. Bu olmadan, bir yöntem imzasını değiştirebilir ve geçersiz kılmalarını değiştirmeyi unutabilirsiniz, @Override ile derleyici sizin için yakalar.

Bu tür bir güvenlik ağına sahip olmak her zaman iyidir.


1
Üst yöntemi değiştirirseniz ve alt sınıf yönteminde @Override kullanmıyorsanız, derleme bir şey söyler mi yoksa sessiz kalır mı? "Geçersiz Kıl" ın kullanımı size daha fazla bilgi verecek mi, öyleyse ne olacak?
djangofan

5

Her yerde kullanıyorum. İşaretleme yöntemleri için çaba konusunda Eclipse'nin benim için yapmasına izin verdim, bu yüzden ek çaba yok.

Sürekli yeniden düzenleme konusunda dindarım .... bu yüzden her şeyi daha düzgün yapmak için kullanacağım.


5
  • Yalnızca yöntem bildirimlerinde kullanılır.
  • Açıklamalı yöntem bildiriminin, süper tipteki bir bildirimi geçersiz kıldığını gösterir.

Sürekli olarak kullanılırsa, sizi büyük bir hain böcek sınıfından korur.

Bu hataları önlemek için @Override ek açıklamasını kullanın: (Hatayı aşağıdaki kodda bulun :)

public class Bigram {
    private final char first;
    private final char second;
    public Bigram(char first, char second) {
        this.first  = first;
        this.second = second;
    }
    public boolean equals(Bigram b) {
        return b.first == first && b.second == second;
    }
    public int hashCode() {
        return 31 * first + second;
    }

    public static void main(String[] args) {
        Set<Bigram> s = new HashSet<Bigram>();
        for (int i = 0; i < 10; i++)
            for (char ch = 'a'; ch <= 'z'; ch++)
                s.add(new Bigram(ch, ch));
        System.out.println(s.size());
    }
}

Kaynak: Etkili Java


Java'da operatör öncelik kurallarının ne olduğunu bilmiyorum, ancak eşittir yönteminiz BUUUUUUUUUUUG bağırıyor! Daha düşük önceliğe sahip (b.first == first) && (b.second == second)olsa bile yazardım . &&==
pyon

Bağlantınızın, bu sayfanın faydalı bölümünü kapsayan bir 'abone olmanız' mesajı gösterdiğini biliyor muydunuz?
Adriano Varoli Piazza

@Adriano: Üzgünüm dostum !! Çaresizim !! 'Cevabı' yazdığımda mevcuttu. Endişeye gerek yok .. kitabı satın al. Buna değer!
jai

5
Eşittir yöntemi geçersiz kılmaz: Orijinal Object::equals, boolean equals(Object)geçersiz kılınmışken equals, boolean equals(Bigram)geçersiz kılmayan farklı bir yöntem imzasına sahiptir. @Override eklenirse equalsbu hata giderilir .
Ming-Tang

3

Geçersiz kılmayı kullanırken dikkatli olun, çünkü daha sonra starUML'de tersine mühendislik yapamazsınız; önce uml yapın.


2

Buradaki bilgelik değişiyor gibi görünüyor. Bugün IntelliJ IDEA 9'u kurdum ve " eksik @Override denetimi " nin artık sadece soyut yöntemleri değil, aynı zamanda uygulanan arayüz yöntemlerini de yakaladığını fark ettim . İşverenimin kod tabanında ve kendi projelerimde, uzun zamandır sadece eski uygulanan soyut yöntemler için @Override kullanma alışkanlığım vardı. Ancak, alışkanlığı yeniden düşünerek, her iki durumda da ek açıklamaları kullanmanın değeri açıktır. Daha ayrıntılı olmasına rağmen, kırılgan taban sınıfına karşı koruma sağlar , arayüz yöntemi adının değiştiği ve türetilmiş bir sınıfta uygulanacak yöntemi öksüz bırakan sorununa (C ++ ile ilgili örnekler kadar mezar değil) .

Tabii ki, bu senaryo çoğunlukla abartıdır; türetilmiş sınıf artık derlenmeyecek, şimdi yeniden adlandırılmış arabirim yönteminin bir uygulaması eksikti ve bugün büyük olasılıkla tüm kod tabanını toplu olarak ele almak için bir Yeniden Adlandırma Yöntemi yeniden düzenleme işlemi kullanılacaktır.

IDEA'nın incelemesinin, uygulanan arayüz yöntemlerini göz ardı edecek şekilde yapılandırılamadığı göz önüne alındığında, bugün hem alışkanlığımı hem de ekibimin kod inceleme kriterlerini değiştireceğim.


2

@Override ek açıklaması, geliştiricinin üst sınıfta veya arabirimde doğru yöntemi geçersiz kılmasının gerekip gerekmediğini denetlemeye yardımcı olmak için kullanılır. Süper yöntemlerin adı değiştiğinde, derleyici yalnızca süper ve alt sınıfla tutarlılığı sağlamak için bu durumu bildirebilir.

BTW, alt sınıfta @Override ek açıklamasını duyurmadıysak, ancak süper bazı yöntemleri geçersiz kıldığımızda, işlev @Override ile bu şekilde çalışabilir. Ancak bu yöntem, süper yöntem değiştirildiğinde geliştiriciyi bilgilendiremez. Geliştiricinin amacını bilmediği için - super yöntemini geçersiz kıl veya yeni bir yöntem tanımla?

Bu nedenle, Polimorfizm'den yararlanmak için bu yöntemi geçersiz kılmak istediğimizde, yöntemin üzerine @Override eklememiz daha iyi olur.


1

Bir yöntemin geçersiz kılındığını belirlemek için mümkün olduğunca kullanıyorum. Scala programlama diline bakarsanız, ayrıca bir geçersiz kılma anahtar kelimesi vardır. Yararlı buluyorum.


0

Geçersiz kıldığınız bir yöntem adında yanlış yazım kullandığınızda (derleyici) yakalamanıza izin verir.


0

Geçersiz kılma ek açıklaması, bir yöntemi üst sınıftan gerçekten geçersiz kılmayı kontrol edip etmediğinizi kontrol etmek için derleyiciden yararlanmak için kullanılır. Bir yöntem adını yanlış yazma hatası, parametreleri doğru eşleştirmeme hatası gibi herhangi bir hata yaparsanız bildirim yapmak için kullanılır


0

izin verildiğinde @ override kodlamak en iyisidir düşünüyorum. kodlamaya yardımcı olur. bununla birlikte, sdk 5 veya 6 olan ecipse Helios için, uygulanan arayüz yöntemleri için @ override ek açıklamasına izin verilir. Galileo için, 5 veya 6, @override ek açıklamasına izin verilmez.


0

Ek açıklamalar, Derleyiciye kodla ilgili meta veriler sağlar ve @Override ek açıklaması, temel sınıf yöntemlerinden herhangi birini geçersiz kıldığımızda kalıtım durumunda kullanılır. Sadece derleyiciye yöntemi geçersiz kıldığını söyler. Yöntemin uygun imzasını takip etmemek veya yöntemin adı vb. Gibi yanlış yazım yapmaktan hoşlanabileceğimiz bazı yaygın hatalardan kaçınabilir.


0

Benim için @Override yöntemin doğru imzasını almamı sağlıyor. Ek açıklamayı koyarsam ve yöntem doğru yazılmazsa, derleyici bana bir şeyin yanlış olduğunu bildirmekten şikayet eder.


0

Basit - üst sınıfınızda bulunan bir yöntemi geçersiz kılmak istediğinizde, @Overridedoğru geçersiz kılma yapmak için ek açıklamayı kullanın. Derleyici, doğru bir şekilde geçersiz kılmazsanız sizi uyaracaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.