Junior
Jaka jest podobieństwo i różnica między zwykłą a abstrakcyjną klasą?
sobes.tech AI
Odpowiedź od AI
W Golang nie ma pojęcia "zwykłej klasy" i "klasy abstrakcyjnej" w formie, w jakiej istnieją one w językach obiektowych typu Java czy C#.
Jednakże, ich funkcjonalność można imitować, używając struktur i interfejsów.
Podobieństwa (używając struktur i interfejsów w Golang):
- Stan (dane): Struktura może zawierać pola, podobnie jak zwykła klasa przechowująca właściwości.
- Zachowanie (metody): Do struktury można dołączać metody, które będą określać jej zachowanie, podobnie jak metody zwykłej klasy.
- Wspólny kontrakt (dla klasy abstrakcyjnej i interfejsu): Interfejs w Golang definiuje zestaw metod, które musi zaimplementować każda struktura "implementująca" ten interfejs. To przypomina to, jak klasa abstrakcyjna lub interfejs w innych językach określa kontrakt dla dziedziczących lub implementujących klasy.
Różnice (w kontekście Golang):
| Cecha | "Zwykła klasa" (struktura z metodami) | "Klasa abstrakcyjna" (interfejs + struktury) |
|---|---|---|
| Tworzenie bezpośrednie | Można utworzyć instancję struktury. | Nie można utworzyć instancji interfejsu. |
| Implementacja metod | Wszystkie metody dołączone do struktury mają implementację. | Interfejs tylko deklaruje metody, ale nie ich implementację. |
| Dziedziczenie | Nie ma dziedziczenia w klasycznym sensie. Można używać kompozycji (wstawianie struktur). | Interfejs nie dziedziczy, ale jest implementowany przez struktury. |
| Obowiązkowość implementacji | Nie ma obowiązku implementowania określonego zestawu metod, oprócz tych dołączonych do struktury. | Każda struktura, która "implementuje" interfejs Golang, musi dostarczyć implementację wszystkich jego metod. |
| Przechowywanie stanu (pól) | Struktura może zawierać pola danych. | Interfejs nie zawiera pól danych. |
Przykład imitacji:
// interfejs imitujący klasę abstrakcyjną
type Shape interface {
Area() float64
Perimeter() float64
}
// struktura imitująca zwykłą klasę
type Circle struct {
Radius float64
}
// implementacja metod interfejsu dla Circle
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * 3.14 * c.Radius
}
// Inna struktura implementująca interfejs
type Rectangle struct {
Width, Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
W tym przykładzie Shape działa jako kontrakt (podobny do klasy abstrakcyjnej lub interfejsu w innych językach), a Circle i Rectangle to konkretne implementacje (odpowiedniki zwykłych klas). Możemy tworzyć instancje Circle i Rectangle, ale nie możemy bezpośrednio tworzyć instancji Shape. Obie struktury muszą również implementować metody Area() i Perimeter(), aby "spełniać" interfejs Shape.