Nhập hai lớp có cùng tên. Làm thế nào để xử lý?


107

Giả sử tôi có một mã như:

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 ?

  }
}

Tôi có nên điền tên lớp đủ điều kiện không? Tôi có thể loại bỏ các câu lệnh nhập không? Một kịch bản như vậy có phổ biến trong lập trình thế giới thực không?


Không hẳn là câu trả lời cho câu hỏi của bạn nhưng trong C #, bạn có thể sử dụng bí danh cho bất kỳ không gian tên nào. Có thể nó là đường chỉ là cú pháp nhưng nó là thực sự hữu ích: msdn.microsoft.com/en-us/library/7f38zh8x.aspx
borjab

Câu trả lời:


154

Bạn có thể bỏ qua các câu lệnh nhập và tham chiếu đến chúng bằng cách sử dụng toàn bộ đường dẫn. Ví dụ:

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

Nhưng tôi sẽ nói rằng sử dụng hai lớp có cùng tên và một hàm tương tự thường không phải là ý tưởng tốt nhất trừ khi bạn có thể làm rõ ràng đó là lớp nào.


2
Nếu đang sử dụng Eclipse, bạn có thể thay đổi tên your.own.Datebằng cách sử dụng ctrl + shift + R. Điều này sẽ tự động thay đổi nó ở mọi nơi bạn đề cập đến nó trong mã của mình, cũng như trong tệp (và tên tệp) của bạn / own / Date.java. Bất kỳ IDE nào khác có thể có tính năng tương tự.
MatrixFrog

16
Tôi không đồng ý với tuyên bố cuối cùng. Nếu bạn muốn thiết kế lớp Date của riêng mình, thì đây Datelà cái tên hoàn hảo. Bạn sẽ sử dụng nó trong hầu hết các mã của mình. Tuy nhiên, đôi khi bạn sẽ cần phải gọi java.util.Datelà đáng chú ý để thực hiện chuyển đổi giữa cả hai.
paradigmatic

2
@MatrixFrog Tính năng trong Eclipse mà bạn đã chỉ định cũng được cung cấp bởi Netbeans IDE. Tính năng này được gọi là "Refactor". Thông tin của bạn không sai nhưng nó không phải là câu trả lời cho câu hỏi được hỏi. Nếu anh ta (Roger) đang phát triển mã đó, thì chắc chắn anh ta biết rằng anh ta có thể thay đổi hoặc cấu trúc lại tên Lớp của mình. Những gì anh ấy đang hỏi khác với câu trả lời mà bạn đã đưa ra.
Yatendra Goel

11
@Yatendra Đó là lý do tại sao tôi thêm nó dưới dạng nhận xét chứ không phải là câu trả lời. Tôi đã mở rộng quan điểm Ellie P. đưa ra ở cuối câu trả lời của cô ấy. Roger có lẽ biết điều đó, nhưng quan điểm của SO là giúp các nhà phát triển khác, không chỉ người đặt câu hỏi. Nếu mọi người không biết về tính năng IDE, họ có thể nghĩ rằng việc chuyển đổi tên bằng tay là không khả thi, vì vậy tôi nghĩ sẽ hữu ích khi đưa thông tin đó vào.
MatrixFrog

5
Cuộc đụng độ tên thường xuyên nhất của tôi xảy ra với org.apache.log4j.Loggerjava.util.logging.Logger. Thông thường, tôi không kiểm soát được bên này hay bên kia; Tôi đang tích hợp mã kế thừa.
kevinarpe

21

sử dụng tên đủ điều kiện thay vì nhập lớp.

ví dụ

//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
Cách tốt nhất là nhập một sử dụng nhiều nhất, bằng cách sử dụng một được sử dụng ít nhất là với đầy đủ classpath
Alpaslan

10

Có, khi bạn nhập các lớp có cùng tên đơn giản, bạn phải tham chiếu đến chúng bằng tên lớp đủ điều kiện của chúng. Tôi sẽ để nguyên các câu lệnh nhập, vì nó cho các nhà phát triển khác biết những gì có trong tệp khi họ làm việc với nó.

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

7

Một cách khác để làm điều đó là phân lớp nó:

package my.own;

public class FQNDate extends Date {

}

Và sau đó nhập my.own.FQNDate trong các gói có java.util.Date.


Tôi thích điều này ngoại trừ (nó đơn giản) tuy nhiên nó không giải quyết được vấn đề khi nói rằng truy cập các phương thức tĩnh.
Justin Ohms

Tôi làm điều này mọi lúc khi tôi muốn sử dụng Hamcrest Matchersvà Mockito Matcherstrong cùng một lớp. Nó dường như hoạt động với các phương thức tĩnh.
Adam Burley

@Kidburla, bạn cũng có thể sử dụng nhập tĩnh miễn là bạn không quan tâm đến trình kết hợp nào đến từ đâu. Tôi thường làm điều này trong các bài kiểm tra đơn vị cho các đối sánh và .whens, .thenReturns , v.v. - loại bỏ khối Mockito.phồng.
CptBartender

Đây là một thực hành xấu. Các lớp không nên được mở rộng trừ khi một số chức năng đang được mở rộng từ lớp gốc.
Partha

3

Nếu bạn có lớp ngày của riêng mình, bạn nên phân biệt nó với dạng lớp Ngày được tạo sẵn. tức là tại sao bạn tạo của riêng bạn. Một cái gì đó như ImmutableDate hoặc BetterDate hoặc NanoDate, thậm chí MyDate sẽ cho biết lý do tại sao bạn có lớp ngày của riêng mình. Trong trường hợp này, chúng sẽ có một tên duy nhất.


3

Bạn có thể nhập một trong số chúng bằng cách sử dụng nhập. Đối với tất cả các lớp tương tự khác, bạn cần chỉ định Tên lớp đủ điều kiện. Nếu không, bạn sẽ gặp lỗi biên dịch.

Ví dụ:

import java.util.Date;

class Test{

  public static void main(String [] args){

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

    // util.Date
    Date utilDate;
  }
}

2

Kịch bản này không quá phổ biến trong lập trình thế giới thực, nhưng cũng không quá xa lạ. Đôi khi xảy ra trường hợp hai lớp trong các gói khác nhau có cùng tên và chúng ta cần cả hai.

Không bắt buộc là nếu hai lớp có cùng tên, thì cả hai sẽ chứa các chức năng giống nhau và chúng ta chỉ nên chọn một trong số chúng.

Nếu chúng ta cần cả hai, thì không có hại gì khi sử dụng nó. Và nó cũng không phải là một ý tưởng lập trình tồi.

Nhưng chúng ta nên sử dụng tên đủ điều kiện của các lớp (có cùng tên) để làm rõ chúng ta cũng đang đề cập đến lớp nào.

:)


2

Tôi gặp phải vấn đề này, ví dụ: khi ánh xạ một lớp này sang lớp khác (chẳng hạn như khi chuyển sang một tập hợp lớp mới để đại diện cho dữ liệu người). Tại thời điểm đó, bạn cần cả hai lớp vì đó là toàn bộ điểm của mã - để ánh xạ cái này sang lớp kia. Và bạn không thể đổi tên các lớp ở cả hai nơi (một lần nữa, công việc là lập bản đồ, không phải thay đổi những gì người khác đã làm).

Đủ điều kiện là một cách. Có vẻ như bạn thực sự không thể bao gồm cả hai câu lệnh nhập, vì Java lo lắng về việc "Người" có nghĩa là gì, chẳng hạn.


2

Nếu bạn thực sự muốn hoặc cần sử dụng cùng một tên lớp từ hai gói khác nhau, bạn có hai tùy chọn:

chọn một để sử dụng trong quá trình nhập và sử dụng tên lớp đủ điều kiện của cái còn lại:

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-luôn sử dụng tên lớp đủ điều kiệ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

Tôi vừa gặp vấn đề tương tự, những gì tôi đã làm, tôi sắp xếp thứ tự thư viện theo trình tự, ví dụ có java.lang.NullPointerException và javacard.lang.NullPointerException. Tôi đã tạo cái đầu tiên làm thư viện mặc định và nếu bạn cần sử dụng cái kia, bạn có thể chỉ định rõ ràng tên lớp đủ điều kiện.


0

Khi bạn gọi các lớp có cùng tên, bạn phải chỉ định rõ ràng gói mà từ đó lớp được gọi.

Bạn có thể làm như sau:

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}";
    }
}

Đầu ra:

Foo{first class}
Foo{second class}

Vui lòng bao gồm mã từ ảnh chụp màn hình trong câu trả lời của bạn.
Thomas Landauer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.