Tôi có một vấn đề với ẩn tên rất khó giải quyết. Đây là một phiên bản đơn giản giải thích sự cố:
Có một lớp học: org.A
package org;
public class A{
public class X{...}
...
protected int net;
}
Sau đó, có một lớp học net.foo.X
package net.foo;
public class X{
public static void doSomething();
}
Và bây giờ, đây là lớp có vấn đề kế thừa A
và muốn gọinet.foo.X.doSomething()
package com.bar;
class B extends A {
public void doSomething(){
net.foo.X.doSomething(); // doesn't work; package net is hidden by inherited field
X.doSomething(); // doesn't work; type net.foo.X is hidden by inherited X
}
}
Như bạn thấy, điều này là không thể. Tôi không thể sử dụng tên đơn giản X
vì nó bị ẩn bởi một kiểu kế thừa. Tôi không thể sử dụng tên đủ điều kiện net.foo.X
vì net
bị ẩn bởi trường kế thừa.
Chỉ có lớp B
trong cơ sở mã của tôi; các lớp net.foo.X
và org.A
là các lớp thư viện, vì vậy tôi không thể thay đổi chúng!
Giải pháp duy nhất của tôi trông như thế này: Tôi có thể gọi một lớp khác đến lượt nó gọi X.doSomething()
; nhưng lớp này sẽ chỉ tồn tại vì sự đụng độ tên, có vẻ rất lộn xộn! Không có giải pháp nào mà tôi có thể gọi trực tiếp X.doSomething()
từ đó B.doSomething()
?
Trong một ngôn ngữ cho phép chỉ định không gian tên toàn cục, ví dụ: global::
trong C # hoặc ::
trong C ++, tôi có thể chỉ cần thêm tiền tố net
toàn cục này, nhưng Java không cho phép điều đó.
net.foo.X
có phương pháp, không org.A.X
!
A
? Thừa kế có thể rất tồi tệ, như bạn đã tìm thấy…
I could call another class that in turn calls X.doSomething(); but this class would only exist because of the name clash, which seems very messy
+1 cho thái độ của mã sạch. Nhưng đối với tôi, có vẻ như đây là tình huống bạn nên đánh đổi. Đơn giản chỉ cần làm điều này và ném một bình luận dài về lý do tại sao bạn phải làm điều đó (có thể là với một liên kết đến câu hỏi này).
public void help(net.foo.X x) { x.doSomething(); }
và gọi vớihelp(null);