Aynı ada sahip iki sınıf içe aktarılıyor. Nasıl idare edilir?


107

Şöyle bir kodum olduğunu söyle:

import java.util.Date;
import my.own.Date;

class Test{

  public static void main(String [] args){

    // I want to choose my.own.Date here. How?
    ..
    // I want to choose util.Date here. How ?

  }
}

Tam nitelikli sınıf isimleri olmalı mıyım? İthalat beyannamelerinden kurtulabilir miyim? Böyle bir senaryo gerçek dünya programlamasında yaygın mıdır?


Aslında sorunuzun cevabı değil, ancak C # 'da herhangi bir ad alanı için bir takma ad kullanabilirsiniz. Bu sadece sözdizimsel şeker olabilir ama gerçekten yardımcı olabilir: msdn.microsoft.com/en-us/library/7f38zh8x.aspx
borjab

Yanıtlar:


154

İçe aktarma ifadelerini atlayabilir ve tüm yolu kullanarak bunlara başvurabilirsiniz. Örneğin:

java.util.Date javaDate = new java.util.Date()
my.own.Date myDate = new my.own.Date();

Ancak, hangisinin hangisi olduğunu gerçekten netleştiremediğiniz sürece, aynı ada ve benzer bir işleve sahip iki sınıf kullanmanın genellikle en iyi fikir olmadığını söyleyebilirim.


2
Eclipse your.own.Datekullanıyorsanız, ctrl + shift + R kullanarak adını değiştirebilirsiniz . Bu, kodunuzda başvurduğunuz her yerde ve ayrıca / kendi / Date.java dosyanızda (ve dosya adı) otomatik olarak değiştirecektir. Başka herhangi bir IDE muhtemelen benzer bir özelliğe sahiptir.
MatrixFrog

16
Son ifadeye katılmıyorum. Kendi Date sınıfınızı tasarlamak istiyorsanız Date, mükemmel bir isim. Kodunuzun çoğunda kullanacaksınız. Bununla birlikte, bazen java.util.Dateikisi arasında dönüşüm yapmak için özellikle aramanız gerekecektir .
paradigmatik

2
@MatrixFrog Eclipse'de belirttiğiniz özellik ayrıca Netbeans IDE tarafından sağlanmaktadır. Bu özellik "Refactor" olarak bilinir. Bilgileriniz yanlış değildi ama sorulan sorunun yanıtı değil. Eğer (Roger) bu kodu geliştiriyorsa, Sınıfının adını değiştirebileceğini veya yeniden düzenleyebileceğini kesinlikle bilir. Sorduğu, verdiğiniz cevaptan farklı.
Yatendra Goel

11
@Yatendra Bu yüzden cevap olarak değil yorum olarak ekledim. Ellie P.'nin cevabının sonunda belirttiği noktayı genişletiyordum. Roger muhtemelen bunu biliyor, ancak SO'nun amacı yalnızca soruyu soran kişiye değil, diğer geliştiricilere de yardımcı olmaktır. İnsanlar IDE özelliğini bilmiyorlarsa, isimleri elle değiştirmenin mümkün olmadığını düşünebilirler, bu yüzden bu bilgiyi eklemenin faydalı olacağını düşündüm.
MatrixFrog

5
En sık kullandığım isim çatışması org.apache.log4j.Loggerve ile ortaya çıkıyor java.util.logging.Logger. Genellikle, bir taraf veya diğer taraf üzerinde kontrolüm yoktur; Eski kod entegrasyonu yapıyorum.
kevinarpe

21

sınıfı içe aktarmak yerine tam nitelikli adı kullanın.

Örneğin

//import java.util.Date; //delete this
//import my.own.Date;

class Test{

   public static void main(String [] args){

      // I want to choose my.own.Date here. How?
      my.own.Date myDate = new my.own.Date();

      // I want to choose util.Date here. How ?
      java.util.Date javaDate = new java.util.Date();
   }
}

6
En iyi uygulama, sınıf yolunda en az kullanılanı kullanarak en çok kullanılanı içe aktarmaktır
Alpaslan

10

Evet, aynı basit adlara sahip sınıfları içe aktardığınızda, onlara tam nitelikli sınıf adlarıyla başvurmalısınız. Diğer geliştiricilere dosyayla çalışırken dosyada ne olduğuna dair bir fikir verdiği için içe aktarma ifadelerini içeride bırakırdım.

java.util.Data date1 = new java.util.Date();
my.own.Date date2 = new my.own.Date();

7

Bunu yapmanın başka bir yolu da alt sınıflara ayırmaktır:

package my.own;

public class FQNDate extends Date {

}

Ve sonra my.own.FQNDate'i java.util.Date içeren paketlere içe aktarın.


Bunu dışında seviyorum (basit) ancak statik yöntemlere erişmek için sorunu ele almıyor.
Justin Ohms

Hamcrest Matchersve Mockito'yu Matchersaynı sınıfta kullanmak istediğimde bunu her zaman yapıyorum . Statik yöntemlerle çalışıyor gibi görünüyor.
Adam Burley

@Kidburla, hangi eşleştiricinin nereden geldiğini umursamadığınız sürece statik içe aktarmaları da kullanabilirsiniz. Sık sık matchers ve birim testlerinde bunu .whens, .thenReturns vb - kaldırır Mockito.kabartmak.
CptBartender

Bu kötü bir uygulamadır. Orijinal sınıftan bazı işlevler genişletilmedikçe sınıflar genişletilmemelidir.
Partha

3

Kendi tarih sınıfınız varsa, bunu yerleşik Tarih sınıfından ayırt etmelisiniz. yani neden kendinizinkini yarattınız. ImmutableDate veya BetterDate veya NanoDate gibi bir şey, MyDate bile neden kendi tarih sınıfınıza sahip olduğunuzu gösterir. Bu durumda benzersiz bir isimleri olacaktır.


3

Bunlardan birini içe aktarmayı kullanarak içe aktarabilirsiniz. Diğer tüm benzer sınıflar için, Tam nitelikli sınıf adlarını belirtmeniz gerekir. Aksi takdirde derleme hatası alırsınız.

Örneğin:

import java.util.Date;

class Test{

  public static void main(String [] args){

    // your own date
    my.own.Date myOwndate ;

    // util.Date
    Date utilDate;
  }
}

2

Bu senaryo, gerçek dünya programlamasında çok yaygın değildir, ancak o kadar da garip değildir. Bazen farklı paketlerdeki iki sınıfın aynı ada sahip olduğu ve her ikisine de ihtiyacımız olduğu görülür.

İki sınıf aynı ada sahipse, her ikisinin de aynı işlevleri içereceği ve bunlardan yalnızca birini seçmemiz zorunlu değildir.

İkisine de ihtiyacımız varsa, bunu kullanmanın bir zararı yoktur. Ve bu da kötü bir programlama fikri değil.

Ancak hangi sınıfa atıfta bulunduğumuzu netleştirmek için sınıfların tam nitelikli adlarını (aynı ada sahip) kullanmalıyız.

:)


2

Örneğin, bir sınıfı diğerine eşlerken (örneğin, kişi verilerini temsil etmek için yeni bir sınıf kümesine geçerken) bu sorunu çözüyorum. Bu noktada, her iki sınıfa da ihtiyacınız var çünkü kodun tüm noktası budur - birini diğerine eşlemek için. Ve her iki yerde de sınıfları yeniden adlandıramazsınız (yine, iş haritalamaktır, başka birinin yaptığı şeyi değiştirmek değil).

Tam nitelikli olmak tek yoldur. Görünüşe göre her iki içe aktarma ifadesini de dahil edemezsiniz, çünkü Java örneğin hangi "Kişi" nin kastettiği konusunda endişelenir.


2

Aynı sınıf adını iki farklı paketten gerçekten kullanmak istiyorsanız veya kullanmanız gerekiyorsa, iki seçeneğiniz vardır:

1-içe aktarmada kullanmak için birini seçin ve diğerinin tam nitelikli sınıf adını kullanın:

import my.own.Date;

class Test{

     public static void main(String[] args){

        // I want to choose my.own.Date here. How?
        //Answer:
        Date ownDate = new Date();

        // I want to choose util.Date here. How ?
        //Answer:
        java.util.Date utilDate = new java.util.Date();

     }
}


2- Her zaman tam nitelikli sınıf adını kullanın:

//no Date import
class Test{

  public static void main(String[] args){

    // I want to choose my.own.Date here. How?
    //Answer:
     my.own.Date ownDate = new my.own.Date();
    // I want to choose util.Date here. How ?
    //Answer:
     java.util.Date utilDate = new java.util.Date();

  }
}

0

Aynı problemi yaşadım, yaptığım gibi, kütüphane sırasını sırayla düzenledim, örneğin java.lang.NullPointerException ve javacard.lang.NullPointerException vardı. İlkini varsayılan kitaplık olarak yaptım ve diğerini kullanmanız gerekirse, tam nitelikli sınıf adını açıkça belirtebilirsiniz.


0

Aynı adlara sahip sınıfları çağırdığınızda, sınıfın çağrıldığı paketi açıkça belirtmelisiniz.

Bunu yapabilirsin:

import first.Foo;

public class Main {
    public static void main(String[] args) {
        System.out.println(new Foo());
        System.out.println(new second.Foo());
    }
}



package first;

public class Foo {
    public Foo() {
    }

    @Override
    public String toString() {
        return "Foo{first class}";
    }
}



package second;

public class Foo {
    public Foo() {
    }

    @Override
    public String toString() {
        return "Foo{second class}";
    }
}

Çıktı:

Foo{first class}
Foo{second class}

Lütfen yanıtınıza ekran görüntüsündeki kodu ekleyin.
Thomas Landauer
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.