Ho un problema con il nascondere il nome che è estremamente difficile da risolvere. Ecco una versione semplificata che spiega il problema:
C'è una classe: org.A
package org;
public class A{
public class X{...}
...
protected int net;
}
Poi c'è una classe net.foo.X
package net.foo;
public class X{
public static void doSomething();
}
E ora, ecco la classe problematica che eredita Ae vuole chiamarenet.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
}
}
Come vedi, questo non è possibile. Non posso usare il nome semplice Xperché è nascosto da un tipo ereditato. Non posso utilizzare il nome completo net.foo.X, perché netè nascosto da un campo ereditato.
Solo la classe Bè nella mia base di codice; le classi net.foo.Xe org.Asono classi di libreria, quindi non posso modificarle!
La mia unica soluzione è questa: potrei chiamare un'altra classe che a sua volta chiama X.doSomething(); ma questa classe esisterebbe solo a causa del nome clash, che sembra molto disordinato! Non c'è soluzione in cui posso chiamare direttamente X.doSomething()da B.doSomething()?
In un linguaggio che consente di specificare lo spazio dei nomi globale, ad esempio global::in C # o ::in C ++, potrei semplicemente aggiungere netquesto prefisso globale, ma Java non lo consente.
net.foo.Xha il metodo, no org.A.X!
A? L'eredità può essere così brutta, come hai scoperto ...
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 per atteggiamento di codice pulito. Ma per me sembra che questa sia una situazione in cui dovresti fare un compromesso. Fallo semplicemente e lancia un lungo e piacevole commento sul motivo per cui hai dovuto farlo (probabilmente con un collegamento a questa domanda).
public void help(net.foo.X x) { x.doSomething(); }e chiamare conhelp(null);