Java'da aşırı operatör yükleme


Yanıtlar:


235

Hayır, Java kullanıcı tanımlı operatör aşırı yüklemesini desteklemez. Java'nın "özel" operatör aşırı yüklemesine yaklaşan tek yönü, dizeler için + 'nın işlenmesidir. Yine de aynı şekilde hareket eden kendi operatörlerinizi tanımlayamazsınız.

Java gibi (ve JVM tabanlı) dil için yaptığı destek operatörü aşırı yüklenmesini, bakmak olabilir KOTLIN veya Groovy . Alternatif olarak, şansınızı bir Java derleyici eklenti çözümü ile bulabilirsiniz .


4
Java'da sarıcı yaratamayacağımızı mı söylüyorsun? Tamsayı gibi SmallInteger gibi mi?
huseyin tugrul buyukisik

3
@ tuğrulbüyükışık: Mevcut tüm ilkel türler için zaten sarmalayıcılar var - ancak kendi yeni sarmalayıcı türünüzü oluşturmak istiyorsanız, dilde özel bir desteğe sahip oldukları için, diğerleri gibi davranmasını sağlayamazsınız.
Jon Skeet

1
teşekkürler, bu konuda googled ve bulamadım. İki ilkel (bir çift ve bir int ---> iyi hassasiyet + iyi aralık) oluşan karmaşık bir değişken yapıp yapamayacağımı bilmek istedim
huseyin tuğrul buyukisik

40
@djaqeel: Operatörün aşırı yüklenmesi, kötü kullanıldığında kodu daha az okunabilir hale getirir . İyi kullanıldığında, okunabilirliği IMO'yu büyük ölçüde artırabilir. Kullandığı kod bak BigIntegerJava, ardından kullanarak benzer kod bakmak BigIntegeroperatörlerini kullanarak C #. Delegelerin OOP ilkelerini nasıl ihlal ettiğini görmüyorum - itirazlarınızdakinden çok daha kesin olmanız gerekiyor. Java tasarımcılarının neden çeşitli özellikler içermediğinin ayrıntılarını bilmiyorum, ancak kaynak baskısının bir karışımı ve dili küçük ve nispeten basit tutma arzusu olduğundan şüpheleniyorum.
Jon Skeet

4
Bunun geç olduğunu biliyorum, ama bir örnek bin tartışmaya değer. Verilen m0bir şekilde Matrixve v0, v1, v2, v3, ve v4yanı Vectors, basitçe size ne kadar sürdüğünü karşılaştırmak doğru aşağıdaki matematiksel ifadeyi yorumlamak m0.transpose().mult(v0.add(v1.mult(v2)).cross(v3)).sub(v4);. Operatör aşırı yüklemesi için destek dahil edilmiş olsaydı, olarak yazılabilirdi m0.transpose() * (v0 + v1 * v2).cross(v3) - v4;.
code_dredd

38

Java'da String türünün birleştirilmesi için operatör aşırı yüklenmesi kullanılır:

String concat = "one" + "two";

Ancak, olamaz kendi operatör aşırı yüklenmeleri tanımlar.


26

+Dizeler için aşırı yüklendiğine işaret eden tüm insanlara ek olarak , -hem kayan nokta hem de tamsayı işlemleri için *ve gibi aşırı yüklenir /.

[değiştir] %ayrıca kayan nokta için aşırı yüklenmiştir, bu da C veya C ++ geçmişine sahip olanlar için biraz sürpriz olabilir.


21

Java, operatörün aşırı yüklenmesine izin vermez. Tercih edilen yaklaşım, sınıfınızda eylemi gerçekleştirmek için bir yöntem tanımlamaktır: a.add(b)yerine a + b. Java gibi C gibi diller dışında kalan diğer bitlerin bir özetini görebilirsiniz: C ve C ++ 'dan kaldırılan özellikler


2
Önemli olan, Java kaynak dosyalarını bağlamdan bağımsız hale getirmenin tasarım hedefidir. Çok büyük (MLOC) okumaya çalışan makro ağır C programları çok uzun bir öğrenme eğrisine sahiptir. Karşılaştırılabilir (veya daha büyük) bir Java programının küçük bir Java programından ayrılması zor değildir. . Gosling dediği gibi: iş için mavi yakalı programcılar için bir dil [Ve herkes düşünen klişe ayrıntı is zararlı uzman kognisyondaki chunking hakkında okumalısınız.]
Tim Williscroft

2
Oracle sayesinde, java.sun.com bağlantılarının hiçbiri çalışmıyor. Mümkünse güncellenmiş bağlantıyı verebilir misiniz?
Syed Aqeel Ashiq

17

Java, operatörün aşırı yüklenmesine izin vermediğinden bunu kendiniz yapamazsınız.

İle bir yandan istisna. + ve + = , String nesneleri için aşırı yüklenmiş.


8
Java'da aşırı yüklenmeye ilişkin başka birçok örnek vardır. Örneğin &, |ve ^için aşırı edilir booleanve ayrılmaz türleri. Ve gerçekten de, aritmetik ve ilişkisel operatörler çeşitli sayısal tipler için aşırı yüklenmiştir. (Elbette, aşırı yüklerin semantiği çok daha yakın ...)
Stephen C

16

Diğerlerinin yanıtladığı gibi: Java, kullanıcı tanımlı operatör aşırı yüklemesini desteklemez.

Belki konu dışı, ama bazı cevaplarda okuduğum bazı şeyler hakkında yorum yapmak istiyorum.

Okunabilirlik hakkında.
Karşılaştırmak:

  1. c = a + b
  2. c = a. ek (b)

Tekrar bak!
Hangisi daha okunabilir?

Kullanıcı tanımlı türlerin oluşturulmasına izin veren bir programlama dili, yerleşik türlerle (veya ilkel türlerle) aynı şekilde hareket etmelerine izin vermelidir.

Dolayısıyla Java, Genel Programlamanın temel prensibini ihlal eder:
Yerleşik türlerdeki nesneleri kullanıcı tanımlı türlerdeki nesnelerle değiştirebilmeliyiz.
(Merak ediyor olabilirsiniz: "Yerleşik nesneler" mi dedi? ". Evet, buraya bakın .)

Dize birleştirme hakkında:

Matematikçiler setlerdeki değişmeli işlemler için + sembolünü kullanırlar.
Bu yüzden a + b = b + a olduğundan emin olabiliriz.
Dize birleştirme (çoğu programlama dilinde) bu ortak matematiksel gösterime uymaz.

a := "hello";
b := "world";
c := (a + b = b + a);

veya Java'da:

String a = "hello";
String b = "world";
boolean c = (a + b).equals(b + a);

Ekstra:
Java eşitliğinde ve kimliğinde nasıl karışık olduğuna dikkat edin. == (eşitlik) sembolü:
a. İlkel tipler için eşitlik.
b. Kullanıcı tanımlı tipler için kimlik kontrolü, bu nedenle eşitlik için equals () işlevini kullanmaya mecburuz.
Ama ... Bunun operatör aşırı yüklenmesi ile ne ilgisi var?
Dil, kullanıcının aşırı yüklenmesine izin verirse eşitlik operatörüne uygun bir anlam verebilir.


Sembol ==, C ve C ++ gibi Java'da eşitlik için kullanılır. Bunun operatörün aşırı yüklenmesi ile ilgisi yoktur.
Hot Licks

2
Java'daki == operatörü yalnızca ilkel türler için Eşitlik anlamına gelir. Kullanıcı tanımlı türler için Kimlik anlamına gelir. C ++ 'da semantik kullanıcı tarafından tanımlanır, ancak yerleşik semantik eşitliği korumalıdır. Dize a = "merhaba"; String b = "merhaba"; boole c = (a == b);
Fernando Pelliccioni

3
İlk yorumunuzda söyledikleriniz yanlış. Sağ? Lütfen, C'de kullanıcı tanımlı türlerde eşitlik ve kimliğin nasıl test edileceğini söyle. Haklısın, eşitlik hakkındaki yorumum OT, ancak bunu açıkladım (bkz. "Ekstralar"). Bir programlama dili oluşturmadığım gerçeği, mevcut bir dili eleştiremediğim anlamına gelmez. Eleştiriyi dini bir savaş olarak gördüyseniz özür dilerim.
Fernando Pelliccioni

1
Uzun şeyleri kısaca söylemek gerekirse: Java berbat.
Kolya Ivankov


6

Java kodunuzla birlikte Xtend'i kullanmanız yeterlidir. Operatör Aşırı Yüklemeyi destekler:

    package com.example;

@SuppressWarnings("all")
public class Test {
  protected int wrapped;

  public Test(final int value) {
    this.wrapped = value;
  }

  public int operator_plus(final Test e2) {
    return (this.wrapped + e2.wrapped);
  }
}

package com.example

class Test2 {

    new() {
        val t1 = new Test(3)
        val t2 = new Test(5)
        val t3 = t1 + t2
    }

}

Resmi web sitesinde, her operatör için uygulanacak yöntemlerin bir listesi var!


5

Ya da Java Groovy yapabilir ve istediğinizi elde etmek için bu işlevleri aşırı yükleyebilirsiniz

//plus() => for the + operator
//multiply() => for the * operator
//leftShift() = for the << operator
// ... and so on ...

class Fish {
    def leftShift(Fish fish) {
        print "You just << (left shifted) some fish "
    }
}


def fish = new Fish()
def fish2 = new Fish()

fish << fish2

Kim harika olmak / kullanmak istemez ki? : D

Hayır, derlenmiş harika JAR'ları Java ile aynı şekilde kullanamazsınız. Hala Java için bir derleyici hatasıdır.


1

C ++ 'dan farklı olarak Java, kullanıcı tanımlı operatör aşırı yüklemesini desteklemez. Aşırı yükleme, dahili olarak java'da yapılır.

+Örneğin (artı) şunları alabiliriz :

int a = 2 + 4;
string = "hello" + "world";

Burada, artı iki tam sayı ekler ve iki dizeyi birleştirir. Java'nın dahili operatör aşırı yüklemesini desteklediğini ancak kullanıcı tanımlı olmadığını desteklediğini söyleyebiliriz.

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.