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, private
ale 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
, Unit2
i UnitTest
są zagnieżdżone wewnątrz Example
dla uproszczenia prezentacji, ale w rzeczywistym projekcie, będę prawdopodobnie mieć tych klas w osobnych plikach (a UnitTest
nawet 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 ExampleEvolved
niezmienionej 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.
protected
była tylko podklasa? Szczerze mówiąc, przez długi czas miałem wrażenie, że takie jest zachowanie