Klasa abstrakcyjna vs. Interfejs w Javie: wyjaśnienie z przykładami

Klasy abstrakcyjne i interfejsy są używane do abstrakcji w Javie. Abstrakcja w programowaniu obiektowym odnosi się do ukrywania szczegółów implementacji przed użytkownikami końcowymi.

W abstrakcji możesz wiedzieć, jakie są funkcjonalności, ale nie możesz wiedzieć, jak zostały zaimplementowane.

Przyjrzyjmy się każdemu z nich i spróbujmy zrozumieć, dlaczego są używane.

Klasa abstrakcyjna

Klasa, która nie może zostać utworzona jako obiekt i może zawierać metody abstrakcyjne lub nie, jest nazywana klasą abstrakcyjną w Javie. Metoda abstrakcyjna to metoda, która po zadeklarowaniu nie ma treści implementacji.

Przykład klasy abstrakcyjnej GraphicObject – Oracle

Możesz utworzyć klasę abstrakcyjną, podając słowo kluczowe abstract przed słowem kluczowym class.

abstract class abstractClass {
    void run() {
        System.out.println("ran");
    }
}

Klasa abstrakcyjna może być rozszerzona o inne klasy. Innymi słowy, można go również podzielić na podklasy.

abstract class AbstractClass {
    void run() {
        System.out.println("ran");
    }
}

class ExtendingAbstractClass extends AbstractClass {
    void newMethod() {
        System.out.println("new");
    }

    @Override
    void run() {
        System.out.println("override");
    }
}

Klasy abstrakcyjne służą do implementacji wspólnych metod wśród wielu klas, które rozszerzają daną klasę abstrakcyjną. Ponadto możliwość definiowania metod abstrakcyjnych w klasach abstrakcyjnych czyni je niezwykle przydatnymi w przypadku klas, które mają podobne metody, ale z różnymi implementacjami. Weźmy przykład.

Rozważmy samochód, który ma pewne funkcje, takie jak start, stop, cofanie itp. Te funkcje są wspólne dla wszystkich typów samochodów.

Ale co z funkcjami automatyzacji, takimi jak samodzielna jazda? Implementacja tych funkcjonalności może być różna dla różnych typów samochodów. Zobaczmy, jak można stworzyć program zorientowany obiektowo z tym związany.

Przede wszystkim utwórz klasę samochodów, która zostanie rozszerzona o wiele klas różnych typów samochodów.

abstract class Car {
    void start() {
        // implementation
        System.out.println("runs car");
    }

    void stop() {
        // implementation
        System.out.println("engine stops");
    }

    void reverse() {
        // implementation
        System.out.println("reverse mode enabled");
    }

    abstract void selfDrive();
}

Metody start(), stop() i reverse() to metody powszechnie stosowane we wszystkich samochodach. Tak więc ich implementacja jest już zdefiniowana w samej klasie Car. Jednak określony typ samochodu może mieć różne implementacje trybu autonomicznego. W ten sposób można zdefiniować selfDrive() jako metodę abstrakcyjną i zaimplementować ją na różne sposoby w różnych klasach różnych typów samochodów.

class CarTypeA extends Car {
    @Override
    void start() {
        super.start();
    }

    @Override
    void stop() {
        super.stop();
    }

    @Override
    void reverse() {
        super.reverse();
    }

    void selfDrive() {
        // custom implementation
        System.out.println("Type A self driving mode enabled");
    }
}
class CarTypeB extends Car {
    // ...all similar methods

    void selfDrive() {
        // custom implementation
        // different implementation than CarTypeB
        System.out.println("Type B self driving mode enabled");
    }
}

Należy zauważyć, że jeśli podklasa nie implementuje wszystkich metod abstrakcyjnych zdefiniowanych w klasie abstrakcyjnej, powinna zostać zadeklarowana jako sama klasa abstrakcyjna.

Interfejs

Interfejs to sposób na poinformowanie klasy, jakie metody muszą zostać przez nią zaimplementowane. Na przykład, jeśli weźmiesz pod uwagę przykład samochodu, ma on kilka podstawowych funkcji. Może się uruchamiać, poruszać i zatrzymywać. Te funkcje są wspólne we wszystkich samochodach.

Tak więc, jeśli implementujesz interfejs samochodu w klasie, musisz zaimplementować wszystkie metody, aby samochód działał poprawnie i bezpiecznie.

Podobnie jak w przypadku klas abstrakcyjnych, nie możemy tworzyć instancji ani tworzyć obiektów interfejsu. Można ją uznać za klasę w pełni abstrakcyjną, ponieważ zawiera tylko metody abstrakcyjne, czyli metody bez ciała implementacyjnego.

Interfejs można utworzyć za pomocą słowa kluczowego interface.

interface CAR {
    void start();
    void stop();
    void move();
}

Zaimplementuj interfejs, używając słowa kluczowego implements podczas definiowania klasy.

class CarTypeB implements CAR {
    public void start() {
        System.out.println("started");
    }

    public void stop() {
        System.out.println("stopped");
    }

    public void move() {
        System.out.println("running");
    }
}

Podobieństwo

Brak instancji jako obiektu jest jedyną wspólną cechą klas abstrakcyjnych i interfejsów.

Różnice

Klasa abstrakcyjnaDziedziczenie i implementacjaInterfejs klasy abstrakcyjnejKlasa może dziedziczyć tylko jedną klasę abstrakcyjną.Klasa może zaimplementować wiele interfejsów.Typy zmiennychMoże mieć zmienne końcowe, niekońcowe, statyczne i niestatyczne.Może mieć tylko zmienne statyczne i końcowe. Typy metod Może zawierać zarówno metody abstrakcyjne, jak i nieabstrakcyjne. Może zawierać tylko metody abstrakcyjne, ale metody statyczne są wyjątkiem. Modyfikatory dostępu Klasa abstrakcyjna może mieć modyfikator dostępu. Sygnatury metod zdefiniowane w interfejsie są domyślnie publiczne. Interfejs nie ma modyfikatora dostępu. Konstruktory i destruktory Może deklarować konstruktory i destruktory. Nie może deklarować konstruktorów ani destruktorów. Szybkość Szybko Wolno Różnice między klasą abstrakcyjną a interfejsem

Kiedy używać klasy abstrakcyjnej i interfejsu?

Używaj klas abstrakcyjnych, gdy:

  • Chcesz udostępnić kilka wspólnych metod i pól wielu klasom.
  • Deklarowanie pól niestatycznych i niekońcowych w celu modyfikacji stanu obiektu, z którym są powiązane.

Możesz używać interfejsów, gdy:

  • Chcesz zdefiniować zachowanie klasy, która implementuje interfejs, ale nie dbasz o sposób, w jaki jest on implementowany.
  • Chcesz się upewnić, że klasa implementuje wszystkie metody, aby działały poprawnie.

Ostatnie słowa

Interfejsy są używane głównie do tworzenia interfejsów API, ponieważ mogą zapewnić strukturę do implementacji funkcjonalności bez martwienia się o rzeczywistą implementację.

Klasy abstrakcyjne są zwykle używane do współdzielenia wspólnych metod abstrakcyjnych i nieabstrakcyjnych między wieloma klasami, które rozszerzają klasę abstrakcyjną, aby uczynić kod bardziej użytecznym.

Dowiedz się więcej o Javie, korzystając z tych kursów online dotyczących javy. Przygotowujesz się do rozmowy o Javie? Oto kilka pytań do wywiadu na temat programowania obiektowego.