Postanowiłem zabrać się do regularniejszej roboty z programowaniem, trafiłem jednak na pewien problem. Otóż dotychczas rzadko korzystałem z dziedziczenia. Była to dla mnie zbędna czarna magia. Jeśli już je robiłem to żeby jak najmniej mi przeszkadzało. Ostatnio trochę poczytałem i uznałem, że przy odpowiednim niewymuszonym podejściu jest to bardzo praktyczne. Ale nie o tym. Otóż dotychczas byłem przekonany, że wszystko co prywatne w klasie abstrakcyjnej dziedziczy się, ale nie ma do tego dostępu w klasie pochodnej. Z protected natomiast sytuację widziałem następująco. Dziedziczy się, klasa pochodna może się do tego pola odwoływać, ale dalej już się nie da. Tymczasem tworząc dwa obiekty różnych klas dziedziczących z jednej, wsadzając je do zbioru o typie klasy abstrakcyjnej mogę się odwoływać do pól protected. Zdaję sobie sprawę, że może to trochę mieszać, napisałem więc na szybko prosty kod, obrazujący tą sytuację.
Mamy program do wyliczania NWD. Klasa Main służy do komunikacji z użytkownikiem i wywołaniu funkcjonalności klas.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a;
int b;
System.out.println("podaj 1 liczbe");
a=scanner.nextInt();
System.out.println("podaj 2 liczbe");
b=scanner.nextInt();
NWD[] nwd = new NWD [2];
nwd[0]=new SubtractingNWD(a,b);
nwd[1]=new ModuloNWD(a,b);
for (NWD n:
nwd) {
System.out.println(n.getNWD());
System.out.println(n.a);
System.out.println(n.b);
}
}
}
Następnie mamy klasę abstrakcyjną NWD
public abstract class NWD {
protected int a;
protected int b;
NWD(int a, int b){
this.a = a;
this.b = b;
}
public abstract int getNWD();
}
Oraz klasy dziedziczące, jedna wyliczająca NWD poprzez reszty z dzielenia, a druga poprzez odejmowanie:
Modulo:
public class ModuloNWD extends NWD {
public ModuloNWD(int a, int b){
super(a, b);
}
public int getNWD() {
int c;
do{
c=a%b;
a=b;
b=c;
}while(b!=0);
return a;
}
}
Oraz odejmowanie:
public class SubtractingNWD extends NWD{
SubtractingNWD(int a, int b) {
super(a, b);
}
public int getNWD() {
while(a!=b){
if(a>b){
a=a-b;
}else
b=b-a;
}
return a;
}
}
Wiem, że w tej sytuacji mógłbym oczywiście podawać zmienne bezpośrednio do funkcji getNWD(), ale chciałbym zrozumieć dlaczego dzieje się tak jak się dzieje oraz dowiedzieć się czy da się to jakoś obejść? Domyślam się, że to kwestia tego, że oba obiekty są przypisane do typu klasy abstrakcyjnej i w ten sposób odwołujemy się do jej pól, ale...No w takim przypadku znowu dziedziczenie traci dla mnie swój urok. Trzaskać gettery i settery też mi się nie podoba, bo to taka pseudo-hermetyzacja i równie dobrze mógłbym zrobić tę zmienną publiczną.