I have a problem with name hiding that is extremely hard to solve. Here is a simplified version that explains the problem:
There is a class: org.A
package org;
public class A{
public class X{...}
...
protected int net;
}
Then there is a class net.foo.X
package net.foo;
public class X{
public static void doSomething();
}
And now, here is the problematic class which inherits from A
and wants to call net.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
}
}
As you see, this is not possible. I cannot use the simple name X
because it is hidden by an inherited type. I cannot use the fully qualified name net.foo.X
, because net
is hidden by an inherited field.
Only the class B
is in my code base; the classes net.foo.X
and org.A
are library classes, so I cannot alter them!
My only solution looks like this:
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! Is there no solution in which I can directly call X.doSomething()
from B.doSomething()
?
In a language that allows specifying the global namespace, e.g., global::
in C# or ::
in C++, I could simply prefix net
with this global prefix, but Java does not allow that.
public void help(net.foo.X x) { x.doSomething(); }
and call withhelp(null);
– Headnet.foo.X
has the method, notorg.A.X
! – StranguryA
? Inheritance can be so nasty, as you've found… – TrinetteI 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 for attitude of clean code. But for me it seems like this is a situation you should do a tradeoff. Simply do this, and throw a nice long comment about why you had to do it (probably with a link to this question). – Masefield