Jakie funkcje są wymagane do orientacji obiektowej?

9

Zastanawiam się tylko, jakie dokładnie funkcje musi zapewnić język lub biblioteka, aby można było ją zdefiniować jako obiektową. Czy orientacja obiektowa jest czymś, co można mniej więcej osiągnąć w dowolnym języku programowania ogólnego przeznaczenia o przyzwoitych funkcjach? A może jest to coś, co można osiągnąć tylko w językach, które reklamują wsparcie programowania obiektowego?

Na przykład spójrz na następujący kod C:

SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE);
SDL_FreeSurface( screen );

lub kod omówiony tutaj .

Teraz powyższy kod nie korzysta z dziedziczenia, polimorfizmu środowiska uruchomieniowego (?), Funkcji wirtualnych itp. Ale wydaje mi się, że jest to raczej OOP.

Czy obiektowa orientacja to po prostu pisanie kodu opartego na tworzalnych i podlegających zniszczeniu strukturach danych, takich jak obiekty, klasy, struktury itp., Które nie wymagają żadnego specjalnego wzorca lub funkcji zapewnianych przez język programowania lub bibliotekę ?

ApprenticeHacker
źródło
2
OOP zazwyczaj wymaga obiektów . Można jednak napisać kod, który wygląda na OOP w większości języków (wątpię, czy można powiedzieć „ten zestaw wygląda na OOP”)
Raynos 31.01.12
Powyższy kod nie używa instrukcji if ani pętli . Nie używa mnożenia ani dodawania. Nie można użyć dwóch wierszy kodu i listy rzeczy, których nie pokazano, aby w ogóle dokonać oceny. Z tych dwóch wierszy kodu mogę wywnioskować, że jest to ściśle leniwy funkcjonalny język programowania, a nie język OO. Użycie dwóch linii kodu w ramach uogólnienia nie jest prawdziwym pytaniem.
S.Lott,
Link jest również zawarte w powyższym kodzie , które moim zdaniem były po. Zauważ też, że to nie jest wyrok , pytam , czy można to uznać za OOP.
ApprenticeHacker
Trywialna odpowiedź brzmi: tak . Chodzi mi o to. Nie możesz - na podstawie przykładów kodu - oceniać OOP. To banalna kwestia definicji. Albo język jest zdefiniowany jako język OOP, albo nie jest. Podane próbki kodu mogą nie wymagać wszystkich funkcji OOP. Rzeczywiście, kod OOP może używać bardzo, bardzo niewielu funkcji. Na przykład w Pythonie 1+2tak naprawdę jest on zorientowany obiektowo. Jest to konstruktor, który buduje nowy obiekt z dwóch istniejących obiektów. Korzystanie z próbek kodu niczego nie ujawnia.
S.Lott,
Co jest złego w używaniu tej definicji i porównywaniu jej z językiem (a nie dwoma przykładami kodu)? en.wikipedia.org/wiki/…
S.Lott

Odpowiedzi:

11

Według Alana Kay, który wynalazł termin „obiektowy”,

OOP oznacza dla mnie tylko wysyłanie wiadomości, lokalne przechowywanie, ochronę i ukrywanie procesów państwowych oraz ekstremalne późne wiązanie wszystkich rzeczy. Można to zrobić w Smalltalk i LISP. Możliwe są inne systemy, w których jest to możliwe, ale nie jestem ich świadomy.

Wiadomości (zaimplementowane w Smalltalk) to koncepcja porównywalna z polimorfizmem, ale raczej potężniejsza (przynajmniej niż rodzaj polimorfizmu obsługiwany przez C ++ lub Javę). Można to zrobić we wszystkich językach, ale jest to raczej bolesne, jeśli nie jest obsługiwane bezpośrednio przez ten język. Zasadniczo oznacza to, że obiekty mogą wysyłać sobie nawzajem wiadomości zawierające wszystko, i mogą reagować w dowolny sposób na otrzymywane wiadomości. Aby w pełni obsługiwać przesyłanie komunikatów, musi istnieć sposób, aby obiekty reagowały elastycznie na komunikaty bez wyliczania ich w kodzie źródłowym (co zasadniczo robi definicje metod / funkcji).

lokalne przechowywanie, ochrona i ukrywanie procesów państwowych - enkapsulacja AKA - może odbywać się na zasadzie konwencji we wszystkich językach, ale to nieco oszustwo. Lokalna retencja na poziomie języka wydaje się być jedyną cechą wszystkich języków, które twierdzą, że są współużytkowane przez OO (i wiele z nich nie) - ogólnie istnieje sposób na tworzenie złożonych typów danych z wieloma instancjami. Z drugiej strony ochrona i ukrywanie odbywa się często tylko na podstawie konwencji.

późne wiązanie wszystkich rzeczy - przesuwana skala, w której C jest naprawdę dalekie od wizji Kay (podobnie jak C ++, podczas gdy Java jest znacznie bliższa). Można go sfałszować (patrz COM), ale będzie to trudny w użyciu.

Zwróć uwagę, że Kay nie wspomina o spadku . W tym samym e-mailu napisał

Nie podobało mi się to, że Simula I lub Simula 67 dziedziczyły (choć myślałem, że Nygaard i Dahl byli po prostu wspaniałymi myślicielami i projektantami). Postanowiłem więc pominąć dziedziczenie jako funkcję wbudowaną, dopóki nie zrozumiałem go lepiej

Michael Borgwardt
źródło
4
Dokładnie w jaki sposób Java i C # są bliżej późnego wiązania niż C ++?
fredoverflow
@FredOverflow: Java leniwie ładuje definicje klas w środowisku wykonawczym, gdy są one używane po raz pierwszy, i robi to domyślnie za pośrednictwem niezwykle elastycznego mechanizmu, który z łatwością pozwala dodawać nowe klasy, a nawet generować je w locie. C ++ wymaga ponownego połączenia plików wykonywalnych lub jawnego ładowania bibliotek. Sytuacja z C # wydaje się mniej wyraźna niż myślałem, więc usunąłem odniesienie do ti.
Michael Borgwardt,
5

W programowaniu obiektowym nie chodzi o funkcje składniowe, to filozofia kodowania i projektowania. U ich podstaw leży koncepcja obiektu , który jest konstrukcją, która grupuje stan z procedurami do działania na nim (lub, w zależności od twojego punktu widzenia, odpowiedzi na wiadomości). Innym ważnym aspektem OOP jest enkapsulacja : zawijanie szczegółów implementacji w nieprzezroczyste struktury i łączenie ich poprzez dobrze zdefiniowane interfejsy. Prawie wszystko inne w teorii OOP sięga do tych dwóch podstaw.

Tak więc do wykonania OOP można użyć dowolnego języka, który może w jakiś sposób modelować obiekty (encje zawierające zarówno dane, jak i kod) i enkapsulację. Na przykład w C można używać wskaźników funkcji do przechowywania funkcji w strukturach, a systemu plików nagłówkowych / źródłowych można używać do realizacji enkapsulacji. To nie jest wygodne, ale wystarczy zrobić OOP. Prawdopodobnie możesz nawet nagiąć coś takiego jak Haskell lub ML do robienia OOP, i nie zdziwiłbym się, gdyby ktoś wymyślił sposób robienia OOP w asemblerze.

W praktyce jednak język można nazwać „obiektowym”, jeśli zapewnia on kompletny zestaw funkcji składniowych do jawnego programowania obiektowego. Zazwyczaj oznacza to, że taki język powinien mieć: * pojęcie obiektu * pojęcie wywołania metody lub przekazania wiadomości * wygodny i bezpośredni sposób kontrolowania dostępu do elementów obiektu * wygodny i bezpośredni sposób definiowania interfejsów

W związku z tym nazwałbym kawałek kodu obiektowym, jeśli jest zgodny z zasadami OOP i używa dostępnej składni OOP.

BTW., Twój przykład kod prawdopodobnie robi use polimorfizm i funkcje wirtualne, choć składnia C nie robi to oczywiste. Nie jestem ekspertem od SDL, ale spodziewam się, SDL_surfaceże będę w stanie reprezentować różne typy powierzchni, każda z własnym zestawem implementacji - umieszczenie czegoś na mapie bitowej pamięci i połączenie z powierzchnią ekranu wymaga radykalnie różnych kod, ale interfejs (funkcje, które przyjmują SDL_surface*jako argument) pozostaje taki sam. Podobnie, implementuje także enkapsulację: nie możesz uzyskać bezpośredniego dostępu do podstawowej reprezentacji powierzchni, musisz przejść przez funkcje, które wiedzą, jak obsługiwać SDL_surface, ponieważ to wszystko, co masz. To dobry przykład tego, jak zrobiłbyś OOP w C.

tdammers
źródło
Streszczenie Typy danych, modelowanie danych i enkapsulacja nie są unikalne dla OO (jak sam o tym krótko wspominasz). Wolałbym opisywać OO w oparciu o jego bardziej unikalne cechy (dynamiczne wiązanie wywołań metod, polimorfizm za pomocą wspomnianych wywołań metod itp.)
hugomg 31.01.12
4

Rozumiem, że OO jest sposobem myślenia i implementacji opartym na założeniu, że zadanie obliczeniowe może wykonać jeden pracownik (obiekt) lub współpraca poszczególnych pracowników (obiektów) poprzez przekazywanie wiadomości między tymi pracownikami ( obiektów) w czasie wykonywania. To zachowanie w czasie wykonywania wymaga solidnych statycznych i dynamicznych konstrukcji, aby je włączyć.

Konkretna składnia implementująca OO nie jest kluczem, który określa, czy język jest OO, czy nie. Na przykład Smalltalk i C # mają różne składnie, ale oba są językami OO (w różnym stopniu). Kluczem jest to, czy dany język zachowuje filozofię (powyżej) i zapewnia wymagane środki implantacji.

Bez szans
źródło
2

Kiedy byłem studentem, nauczono mnie, że programowanie obiektowe opiera się na trzech filarach:

  • kapsułkowanie ,
  • polimorfizm i
  • spadek .

Język będzie musiał obsługiwać te funkcje , aby zostać uznany za język obiektowy.

Zauważ, że opisuje to zestaw funkcji zamiast składni . Stąd, czy musisz pisać

type obj; // or type obj = new type;
obj.func(arg);

lub

type* ptr = create_type();
func(ptr, arg); 

nie ma znaczenia

Możesz więc rzeczywiście programować zgodnie z paradygmatem obiektowym w C. Jednak język nie oferuje wsparcia dla tego, co czyni z niego dość bolesne ćwiczenie. Dlatego C nie jest uważany za język obiektowy.

sbi
źródło
2
Nauczanie tych „filarów” prawdopodobnie wyrządziło światu więcej szkody niż pożytku. Kapsułkowanie jest dobre, ale o to chodzi.
tdammers
1
Są na tej liście, więc wydaje się, że są powszechnie akceptowane: en.wikipedia.org/wiki/…
S.Lott
Czy możesz wyjaśnić, dlaczego polimorfizm i dziedziczenie są złe?
MathAttack 31.01.12
@MathAttack: Mówisz do mnie? Ponieważ z pewnością tego nie powiedziałem.
sbi
1
@missingno: Coś nie musi być unikalne dla niektórych paradygmatów, aby uznać je za ważne dla odróżnienia paradygmatu. Hermetyzacja nie musi już być unikalna dla OOP, ponieważ funkcje muszą być unikalne dla programowania strukturalnego.
sbi
2

Państwo może zrobić OO w każdym przyzwoitym językiem ogólnego przeznaczenia.

To łatwiej to zrobić w „oo” języka, bo trzeba idiomatyczne konstrukcje dostępne i nie trzeba uciekać się do czegoś podobnego oo in C - co jest możliwe, ale straszne.

To, czy konstrukcje OO są dostarczane przez sam język, przez jego standardową bibliotekę, czy przez inną bibliotekę, nie ma większego znaczenia, ponieważ niektóre języki (np. Scala) pozwalają bibliotekom dodawać konstrukcje językowe, tak że z punktu widzenia programisty jest to prawie niemożliwe rozróżnić, które rzeczy są dostarczane przez podstawowy język, a które przez bibliotekę.

Joonas Pulakka
źródło
2

Jeśli spojrzysz na szereg języków, które są powszechnie akceptowane jako OO, i tych, którzy tego nie robią, test wydaje się być wsparciem dla polimorfizmu inkluzyjnego (inaczej polimorfizmu podtypu, ale polimorfizm inkluzyjny jest terminem używanym przez Cardellego w artykuł, który wprowadził mnie, i myślę, że wiele innych, do klasyfikacji rodzajów polimorfizmu). IE możliwość, aby niektóre zmienne miały wartości różnych typów oraz możliwość wysyłania niektórych wywołań do różnych procedur w zależności od typu jednej lub kilku wartości. Cała reszta była obecna w językach nieakceptowanych jako OO lub brakowało w językach dobrze akceptowanych jako OO.

Dwie inne główne cechy związane z językami OO zostały dostarczone przez języki inne niż OO:

  • Hermetyzacja jest dość dobrze zapewniana przez Ada83;
  • Dziedziczenie zapewnia Oberon (Oberon jest interesujący, Wirth chciał zapewnić język OO z jak najmniejszą ilością cruft, ale musiał ponownie przemyśleć swoją koncepcję, aby go zdobyć - Oberon-2 to OO).
AProgrammer
źródło
1

Orientacja obiektu jest zdefiniowana jako

sprawdź także wpisy w Wikipedii. są to cechy, które musi zapewnić język, aby można go było zdefiniować jako obiektowy.

rozważ swój kod obiektowy, jeśli jest on zorientowany obiektowo. nawet jeśli napiszesz coś, co wydaje się proceduralne, będzie działać na metody w obiektach klas wykorzystujących polimorfizm poprzez enkapsulację [może] :)

odnośnie twojego ostatniego pytania odpowiedź jest prawdopodobnie. tak. obiektowo zorientowany polega po prostu na metodach na obiektach i przekazuje je jako parametry.

Makach
źródło
3
Zdefiniowany przez kogo?
Michael Borgwardt,