szukasz konkretnego przypadku użycia, w którym zarówno podklasa, jak i klasa w tym samym pakiecie muszą uzyskać dostęp do chronionego pola lub metody ...
Cóż, dla mnie taki przypadek użycia jest raczej ogólny niż konkretny i wynika z moich preferencji:
- Zacznij od możliwie jak najściślejszego modyfikatora dostępu, uciekając się do słabszego (-ych) dopiero później, gdy uzna to za konieczne.
- Testy jednostkowe powinny znajdować się w tym samym pakiecie co testowany kod.
Z góry mogę rozpocząć projektowanie dla moich obiektów z domyślnymi modyfikatorami dostępu (zacznę od, privateale skomplikowałoby to testowanie jednostek):
public class Example {
public static void main(String [] args) {
new UnitTest().testDoSomething(new Unit1(), new Unit2());
}
static class Unit1 {
void doSomething() {} // default access
}
static class Unit2 {
void doSomething() {} // default access
}
static class UnitTest {
void testDoSomething(Unit1 unit1, Unit2 unit2) {
unit1.doSomething();
unit2.doSomething();
}
}
}
Dygresja w powyższym fragmencie, Unit1, Unit2i UnitTestsą zagnieżdżone wewnątrz Exampledla uproszczenia prezentacji, ale w rzeczywistym projekcie, będę prawdopodobnie mieć tych klas w osobnych plikach (a UnitTestnawet w osobnym katalogu ).
Następnie, gdy zajdzie taka potrzeba, osłabiłbym kontrolę dostępu z domyślnych do protected:
public class ExampleEvolved {
public static void main(String [] args) {
new UnitTest().testDoSomething(new Unit1(), new Unit2());
}
static class Unit1 {
protected void doSomething() {} // made protected
}
static class Unit2 {
protected void doSomething() {} // made protected
}
static class UnitTest {
// ---> no changes needed although UnitTest doesn't subclass
// ...and, hey, if I'd have to subclass... which one of Unit1, Unit2?
void testDoSomething(Unit1 unit1, Unit2 unit2) {
unit1.doSomething();
unit2.doSomething();
}
}
}
Widzisz, mogę zachować kod testu jednostkowego w ExampleEvolvedniezmienionej postaci, ponieważ chronione metody są dostępne z tego samego pakietu, nawet jeśli dostęp do obiektu nie jest podklasą .
Potrzebne mniej zmian => bezpieczniejsza modyfikacja; w końcu zmieniłem tylko modyfikatory dostępu i nie modyfikowałem metod Unit1.doSomething()i działań Unit2.doSomething(), więc naturalne jest oczekiwanie, że kod testu jednostkowego będzie kontynuowany bez modyfikacji.
protectedbyła tylko podklasa? Szczerze mówiąc, przez długi czas miałem wrażenie, że takie jest zachowanie