Co to jest metoda abstrakcyjna?
Metoda abstrakcyjna to metoda, która nie ma implementacji. Oznacza to, że ma tylko deklarację, więc znasz nazwę, zwracany typ i akceptowane zmienne. Oto przykład podstawowej metody abstrakcyjnej:
public abstract int example(int a1, int a2);
Kiedy spojrzysz na tę metodę, możesz stwierdzić, że zwraca ona liczbę całkowitą i przyjmuje dwie liczby całkowite jako argument. Nie możesz powiedzieć, w jaki sposób ta metoda jest wdrażana. To dlatego, że aby go zaimplementować, musisz go zastąpić. Tworząc abstrakcyjną metodę w Javie, musisz przestrzegać kilku wskazówek, w przeciwnym razie program nie skompiluje się poprawnie. Pamiętać:
-
Abstrakcyjne metody Java nie mają implementacji. Oznacza to, że nigdy nie powinny następować po nich nawiasy klamrowe i treść, która mówi, w jaki sposób należy stosować metodę. Jest po prostu zakończony średnikiem.
-
Jeśli utworzysz metodę abstrakcyjną, można ją umieścić tylko w klasie abstrakcyjnej. Oznacza to, że nie możesz mieć konkretnej klasy, która zawiera w sobie metodę abstrakcyjną.
I. Na marginesie, jeśli masz klasę abstrakcyjną, może ona zawierać konstruktory. Nie musi to być jednak metoda abstrakcyjna. -
Gdy klasa konkretna rozszerza klasę abstrakcyjną, musi również implementować wszystkie metody abstrakcyjne klasy nadrzędnej, w przeciwnym razie nie może być konkretna i musi zostać uznana za abstrakcyjną.
Rozszerzanie abstrakcyjnych klas Java
Powiedzmy, że chcemy napisać program o podstawowych kształtach, który zwróci obwód i pole. Tworzymy więc nadrzędną klasę abstrakcyjną. Ale ponieważ każdy kształt ma swoje własne zasady, każdy musi być obliczany inaczej, dlatego piszemy abstrakcyjną klasę Shape w następujący sposób:
abstract class Shape {
String shapeName = " ";
Shape(String name) {
this.shapeName = name;
}
abstract double area();
abstract double perimeter();
}
Teraz, jeśli chcemy faktycznie używać tych abstrakcyjnych metod, musimy rozszerzyć abstrakcyjną klasę nadrzędną Java Shape , a następnie utworzyć instancję metod. Tak więc każda konkretna klasa musi implementować abstrakcyjne metody obszaru i obwodu.
class Quadrilateral extends Shape
{
double length, width;
Quadrilateral(double l, double w, String name)
{
super(name);
this.length = l;
this.width = w;
}
@Override
public double perimeter()
{
return ((2*length)+(2*width));
}
@Override
public double area()
{
return (length*width);
}
}
Implementing the Quadrilateral class would then look like this
class Main
{
public static void main (String[] args)
{
// creating a Quadrilateral object using Shape as reference
Shape rectangle = new Quadrilateral(3,4, "Rectangle");
System.out.println("Area of rectangle is " + rectangle.area());
System.out.println("Perimeter of rectangle is " + rectangle.perimeter());
}
}
Wyjście z konsoli wygląda wtedy tak:
Area of rectangle is 12.0
Perimeter of rectangle is 14.0
Zauważ, że klasa Quadrilateral nie musi tworzyć instancji konstruktora Shape(String name) z klasy nadrzędnej Shape . To dlatego, że nie jest to metoda abstrakcyjna. Jeśli jednak zaimplementowałbyś tylko obszar lub obwód w klasie, nowa klasa musiałaby być abstrakcyjna, ponieważ nie obejmowała obu. Możesz także używać metod abstrakcyjnych w interfejsach.
Abstrakcyjne metody Java z interfejsami
Przyjrzyjmy się szybko, czym jest interfejs i czym różni się od klasy abstrakcyjnej. W interfejsie wszelkie zmienne zadeklarowane w interfejsie są publiczne, statyczne i ostateczne. Z drugiej strony klasy abstrakcyjne mają tylko zmienne niekońcowe. Wszystko w interfejsie jest domyślnie publiczne. Klasa abstrakcyjna może być prywatna, chroniona, publiczna itd. Wreszcie, klasa nie rozszerza interfejsu, tylko go implementuje. Przed JDK 8 interfejs nie mógł zawierać niczego poza metodami abstrakcyjnymi. Teraz interfejs może mieć metody domyślne i statyczne. Z tego powodu najlepsze praktyki odeszły od używania metod abstrakcyjnych jako rozszerzalnych szablonów i skupiły się na interfejsach i ich implementacji. Więc jeśli miałbyś stworzyć Shape jako interfejs, a następnie zaimplementować go jako czworobok, Jak by to wyglądało? Po pierwsze, musiałbyś zrezygnować z konstruktora Shape(String name) . Wyglądałoby to tak przy użyciu tylko dwóch abstrakcyjnych metod:
interface Shape {
abstract double area();
abstract double perimeter();
}
So the Quadrilateral class would then look like this:
class Quadrilateral implements Shape {
double length, width;
Quadrilateral(double l, double w) {
this.length = l;
this.width = w;
}
@Override
public double perimeter() {
return ((2*length)+(2*width));
}
@Override
public double area() {
return (length*width);
}
}
Wreszcie, użycie nowego Czworokąta podczas implementacji interfejsu Shape byłoby bardzo podobne:
class Main
{
public static void main (String[] args)
{
// creating a Quadrilateral object using Shape as reference
Shape rectangle = new Quadrilateral(3,4);
System.out.println("Area of rectangle is " + rectangle.area());
System.out.println("Perimeter of rectangle is " + rectangle.perimeter());
}
}
A wydruk z konsoli wyglądałby tak:
Area of rectangle is 12.0
Perimeter of rectangle is 14.0
Jeśli chcesz dowiedzieć się więcej o różnicach między interfejsami a klasami abstrakcyjnymi, więcej informacji znajdziesz tutaj.
Ale po co używać abstrakcyjnych metod Java?
Istnieje wiele powodów, dla których używane są metody abstrakcyjne w Javie i dlaczego warto się z nimi oswoić. Oto trzy krótkie powody, dla których warto ich używać, gdy jest to właściwe.-
Unikaj powielania wysiłków – spójrz wstecz na nasze przykładowe kodowanie; wyobraź sobie, że ty i twój zespół musicie stworzyć klasy dla kształtów innych niż prostokąt. Ile różnych sposobów możesz wymyślić, aby zaprojektować tę klasę? Dziesięć? Piętnaście? I to jest prosty problem. Wyobraź sobie coś znacznie bardziej złożonego. Ty i twój zespół możecie wymyślić sto sposobów. Wtedy stanąłbyś przed trudnym zadaniem utkania ich razem w spójny program. To prowadzi nas do następnego punktu: definiowania implementacji.
-
Metody abstrakcyjne w Javie pozwalają na zdefiniowanie użycia i implementacji – Kiedy używasz abstrakcyjnej klasy lub interfejsu, a z założenia metod abstrakcyjnych, definiujesz, w jaki sposób inne osoby będą wchodzić w interakcje z twoim interfejsem. Dzięki temu wiedzą, jakich zmiennych powinni używać i jakich typów zwrotów mogą się spodziewać.
Chociaż mogą je zastępować i tworzyć konkretne klasy, które implementują Twój interfejs w unikalny sposób, nadal ustalasz podstawowe zastosowanie swojego kodu. Jeśli ktoś chce zaimplementować Shape, musi zastąpić lub zaimplementować zarówno obwód, jak i obszar. - Czytelność i debugowanie — Posiadanie metod abstrakcyjnych zwiększy czytelność kodu. Kiedy piszesz klasę, która implementuje interfejs, wiesz, czego szukać. Wiesz, że każda abstrakcyjna metoda w interfejsie będzie w implementacji, a to ułatwia czytanie i śledzenie wszelkich błędów. Metody abstrakcyjne to dopiero początek nauki prawidłowego wykorzystywania polimorfizmu w Javie i innych językach obiektowych. Kiedy zaczniesz je rozumieć i używać, rozpocznie się zupełnie nowy rozdział Twojej przygody z kodowaniem.
GO TO FULL VERSION