Modyfikator abstract

Modyfikator abstract występujący przy deklaracji klasie oznacza, że mamy do czynienia z definicją, która jest nie kompletna lub też powinna być za taką uważana. Tylko klasa tak oznaczona może zawierać metody, które nie posiadają implementacji. Dana klasa ma metody abstrakcyjne, jeżeli:

  • w klasie jest umieszczona jakakolwiek metoda oznaczona jako abstract
  • jakakolwiek klasa nadrzędna posiada metody abstrakcyjne, które nie zostają implementowane
  • klasa dziedziczy pośrednio lub bezpośrednio interfejs i nie ma implementuje wszystkich jego metod

Klasa abstrakcyjną jest używana w celu uogólnienia zbioru innych klas (zawiera pewne wspólne właściwości tych klas). Może także część tych właściwości definiować, pozwala natomiast zdefiniować interfejs dostępu do innych właściwości, których implementacja musi już nastąpić w którejś klasie potomnej.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
abstract class Figura {

    private int kolor;
   
    public void setKolor(int kolor) {
        this.kolor = kolor;
    }
   
    public abstract void rysuj();
   
}

class Kolo extends Figura {

    private int promien;
   
   
    @Override
    public void rysuj() {
        // implementacja rysowania, przy wykorzystaniu
        // zdefiniowanego wcześniej koloru
    }
}

class Program {
    public static void main(String[] args) {
        Kolo kolo = new Kolo();
       
        Figura kwadrat = new Figura() {
           
            @Override
            public void rysuj() {
                // implementacja rysowania kwadratu
            }
        };
    }
}

Nie można utworzyć obiektu przy wykorzystaniu klasy abstrakcyjnej, jeżeli nie zdefiniuje się wszystkich metod abstrakcyjnych.

Klasa powinna być oznaczona jako abstrakcyjna tylko wtedy, gdy zależy nam na tworzeniu klas potomnych w celu utworzenia pełnej implementacji.

Modyfikator final

Klasa może zostać zdefiniowana jako finalna przy użyciu modyfikatora final. Użycie go przy deklaracji klasy oznacza, że nie można dziedziczyć po danej klasie, jej implementacja jest ostateczna i nie ma możliwości jej modyfikowania.

Przykładami takich klas są np. klasy systemowe: String, Integer czy Long.

1
2
3
4
5
6
7
8
9
10
final class Kwadrat {
   
    int szerokosc;
    int wysokosc;
    int kolor;
   
    public void rysuj() {
       
    }
}

Próba dziedziczenie po podanej klasie spowoduje wygenerowanie komunikatu błędu przez kompilator.

Modyfikatory abstract oraz final wzajemnie się wykluczają (nie można jednocześnie nakazać dziedziczenia oraz zabronić go).

Podsumowanie

Podsumowanie użycia modyfikatorów final i abstract
Modyfikator Użycie w klasie Użycie w interfejsie Użycie w typie enum
abstract Klasa nie finalna może zostać oznaczona jako abstrakcyjna

Klasa która zawiera metody oznaczone jako abstract musi zostać oznaczona także jako abstrakcyjna

Nie można utworzyć obiektu bezpośrednio z klasy abstrakcyjnej (chyba że od razu utworzymy implementację metod abstrakcyjnych)

Dozwolone, ale niepotrzebne,
z założenia interfejs jest abstrakcyjny.
Zabronione.
final Tylko klasa nie abstrakcyjna może zostać oznaczona jako ostateczna.

Klasa zawierająca metody oznaczone jako final nie musi być klasą finalną.

Klasa oznaczona jako final nie może posiadać klas potomnych (nie da się jej rozszerzyć).

Zabronione. Zabronione.

Źródła