2015-07-07 25 views
5

Więc mamynie można uzyskać dostępu do metody chroniony przed klasą dziecięcej

public abstract class A{ 
    protected abstract String f(); 
} 

public class B extends A{ 
    protected String f(){...} 
} 

public class C extends A{ 
    protected String f(){ 
     A b = (A) Class.forName("B", true, getClass().getClassLoader()).newInstance(); 
     return b.f(); 
} 

To nie pozwala mi na dostęp b.f(), mówiąc, że B.f() znajduje się w chronionym zakresie, jednak f był chroniony przez A i od C rozszerza A, powinien również uzyskać dostęp do f().

+0

Dlaczego nie stworzyć nową instancję jak: A, b = (A) new B(); ? – Dmitry

+0

B jest dostępne tylko w czasie wykonywania. Jeśli naprawdę chcesz wiedzieć, B to 'com.android.okhttp.HttpsHandler', a A to' URLStreamHandler' –

+0

Możesz rozwiązać swoją sprawę za pomocą refleksji, ale byłoby bardziej pomocne, gdybyś opublikował swój * oryginalny * problem. Którą metodą 'HttpsHandler' próbujesz wywołać i dlaczego tego potrzebujesz. Zobacz [problem XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Rozważ otwarcie nowego pytania z pierwotnym problemem. –

Odpowiedz

2

Chroniony modyfikator określa, że ​​członek może być dostępny tylko w swoim pakiecie (jak w pakiecie-prywatny), a dodatkowo przez podklasę swojej klasy w innym pakiecie.

Jeśli chcesz uzyskać dostęp do B.f(), trzeba mieć klasę C zdefiniowane w tym samym opakowaniu jako B.

+0

, ale ten poziom dostępności można osiągnąć, używając żadnych modyfikatorów (znanych jako "pakiet prywatny"). Jeśli podklasa, która uzyskuje dostęp do metod chronionych musi w tym samym pakiecie, oznacza to, że pakiety modyfikatory prywatne i chronione działają tak samo? Myślę, że podklasa, która uzyskuje dostęp do metod chronionych, może znajdować się w dowolnym pakiecie. Popraw mnie, jeśli nie mam racji. – Dmitry

+0

Masz rację. Odpowiedź próbuje rozwiązać problem, jak jest to określone w pytaniu. –

+1

Teraz widzę. Ale zmienna b jest typu A, a instancja B() jest rzutowana na A. Ta chwila jest interesująca, dlaczego dostęp jest nielegalny – Dmitry

0

Nie, ponieważ kompilator nie wie, czy b jest wystąpieniem B, C lub innych klas zewnętrznych.

Załóżmy, że istnieje klasa D taka, że ​​D extends A w innym pakiecie. Jeśli b jest instancją D (kompilator nie wie) b.f() powinno być zabronione, jeśli dostęp jest protected (nie można uzyskać dostępu przez klasy w innych pakietach).

+0

tak długo, jak b jest literą A, a literą A jest f, co to ma znaczenie? –

+0

@ Doom777 Przypuśćmy, że teraz 'b' jest' D', gdzie 'D rozszerza A' i jest zdefiniowane w innym pakiecie z' protected' 'f()' method. Biorąc pod uwagę "D", "A" jest w "innym pakiecie", więc 'A' nie ma dostępu do metod' chronionych' w 'D'. Jednak kompilacja nie wie, czy 'b' jest' B', 'C' lub' D', więc 'b.f()' musi być zabronione (w przypadku, gdy 'b' jest instancją' D'). – tony200910041

+0

Myślę, że ponieważ 'f' został zdefiniowany pierwotnie w' A', powinien zawsze pozostać jako dziecko 'A' lub freer, i dostępny dla wszystkich' A's i jego podklas –