Gdzie w systemie obiektowym powinieneś, jeśli w ogóle, wybierać struktury (w stylu C) zamiast klas?

9

C i najprawdopodobniej wiele innych języków zapewnia structsłowo kluczowe do tworzenia struktur (lub czegoś podobnego). Są to (przynajmniej w C), z uproszczonego punktu widzenia, takie jak klasy, ale bez polimorfizmu, dziedziczenia, metod itd.

Pomyśl o zorientowanym obiektowo (lub paradygmacie) języku o strukturach typu C. Gdzie wybrałbyś je zamiast klas? Teraz nie sądzę, aby można było ich używać z OOP, ponieważ klasy wydają się zastępować ich cele, ale zastanawiam się, czy istnieją sytuacje, w których mogłyby być one preferowane nad klasami w programach zorientowanych obiektowo i w jakich sytuacjach. Czy są takie sytuacje?

Anto
źródło
Jakiego języka używasz? Co publikujesz? Większość współczesnych języków OO, z wyjątkiem Java, obsługuje właściwości w taki czy inny sposób.
kevin cline

Odpowiedzi:

16

W niektórych książkach istnieje różnica między obiektami niosącymi stan i obiektami zapewniającymi funkcjonalność. Dokładne warunki różnią się w zależności od źródła. Ale ogólnie rzecz biorąc, te pierwsze wyróżniają się szeregiem pól i całą masą prostych par getters-setters (i może konstruktora).

Są to szczególnie powszechne w Javie, dla klas, które są wyraźnie oznaczone jako „możliwe do serializacji”.

Argumentowałbym, że tego rodzaju klasy są najbardziej sensowne jako struktury, jeśli uważasz, że nie ma potrzeby bezpośredniego ukrywania elementów (np. W przypadku typów zagnieżdżonych).

Uri
źródło
1
Robert C Martin nazywa je „obiektami do przesyłania danych” w Clean Code .
user16764
5

W C nie ma klas, więc structjest sposób na pakowanie danych. W C ++ structjest to to samo, co classz tym wyjątkiem, że dziedziczenie i dostęp do elementu są publicdomyślnie, a nie private. C # ma również coś w rodzaju struct, ale nie znam wystarczającej liczby C #, aby to skomentować. Common Lisp ma defstructformę, która działa tak bardzo jak Cs, structjak to możliwe, biorąc pod uwagę różnicę językową, i różni się od klasy Common Lisp Object System.

Istnieje jednak różnica koncepcyjna między pokrewnym pakietem danych a prawdziwą klasą, aw C ++ structjest często używany do pakietu danych, podczas gdy classjest używany do obiektów, które powinny mieć własne zachowanie. Jako wytłumaczenie powiedziałbym, że a classoznacza coś, o czym można powiedzieć coś użytecznego, na przykład niezmiennik klasy, podczas gdy a structbyłby luźniej sprzężony z wartościami danych tak naprawdę niezbyt zależnymi od innych.

David Thornley
źródło
6
Różnica między a structa classjest bardziej znacząca w języku C # - wielką rzeczą jest to, że a structjest typem wartości, a a classjest typem odniesienia. Microsoft zaleca, aby nie używać a, structjeśli zawartość będzie większa niż 16 bajtów.
Carson63000
0

Na bardzo podstawowym poziomie, jaka jest różnica między strukturą a czystą klasą danych (taką, która nie ma żadnej funkcjonalności poza modułami dostępu do właściwości)?

Tak naprawdę tylko ślad pamięci.

biziclop
źródło
0

Przyjęta odpowiedź jest dobra. Chciałbym tylko dodać ...

Czasami lepiej jest umieścić metodę w klasie. Innym razem lepiej jest mieć funkcję zewnętrzną, w której struktur / klasa jest przekazywana jako parametr (nawet jeśli wykonujesz styl OOP).

przykład kiedy wstawić metodę do klasy: Rectangle.CaclulateArea ()

przykład kiedy umieścić funkcję poza klasą: Canvas.Draw (Rectangle rect)

możesz umieścić Draw () wewnątrz Prostokąta i to zadziała. Ale rysowanie jest operacją zależną od poziomu. Nie rysowałbyś po stronie serwera, ale po stronie klienta. Draw () nie ma sensu nawet istnieć na serwerze. Jednak „CalculateArea ()” jest niezależny od warstwy i jest prawdziwym atrybutem prostokąta, dlatego lepiej jest uwzględnić go jako metodę członka.

mike30
źródło
0

Dla mnie duża różnica polega na tym, czy istnieje niezmiennik klasy, czy nie.

Innymi słowy: czy mogę w dowolnym momencie zmienić dowolne pole na dowolną wartość? Jeśli tak, jest to struktura; Jeśli nie, to klasa.

Typowym przykładem struktury jest punkt 2D, zawierający tylko element X i Y, który może mieć dowolną wartość i jest całkowicie od siebie niezależny. Publiczny dostęp jest dopuszczalny.

Przykładem klasy jest kombinacja wskaźnika do tablicy znaków i pola długości: długość zależy od wartości wskaźnika, a zatem nie powinna być strukturą. Pola powinny być prywatne, a dostęp powinien przechodzić przez ustawiające i pobierające, aby zapewnić niezmienność klasy.

Sjoerd
źródło
0

1) Sieć struct: struktury przesyłane przewodem.

Mówiąc bardziej ogólnie i formalnie, każda klasa, której potrzebujesz, to POD, trywialny, standardowy układ lub powiązana koncepcja. Aby uzyskać doskonałe omówienie tych pojęć z przykładami, zobacz tę odpowiedź (dotyczy C ++ 11).

2) Funkcje (w szczególności predykaty), które przeszlibyśmy na funkcje takie jak std::remove_if. Inaczej mówiąc, klasy podobne do / dziedziczone z std::binary_functionlub podobne.

3) Koncepcje metaprogramowania, które mogą zawierać tylko publiczne constexpri / lub typedefs.

Edycja: Uwaga: Ta odpowiedź dotyczy klas C ++ vs struktur.

haelix
źródło