🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.objects
Article #13583

Re: Czy interfejs to to samo co klasa czysto abstrakcyjna ?

#13583
From: Sektor van Skijlen
Date: Sun, 20 Nov 2005 21:01
247 lines
13484 bytes
Dnia Sun, 20 Nov 2005 21:01:19 +0100, Filip Sielimowicz skrobie:

> Użytkownik "Sektor van Skijlen" <ethouris@pl.wp.spamu.lubie.nie.invalid> napisał w
> wiadomo?ci news:dlqam1$711$1@kujawiak.man.lodz.pl...

> > Ech...
> >
> > Spróbuj mnie umotywować jako?, żeby nie zacz?ł przeklinać.
> >
> > Tu już nie o to chodzi, że pleciesz niestworzone dyrdymały w ogóle nie
> > sprawdziwszy, na ile to się zgadza z prawd?. Chodzi o to, że pleciesz je mimo
> > tego, że ja już kiedy? całkiem niedawno WŁA?NIE NA TEJ GRUPIE wyja?niałem, że
> > w C++ wcale tak nie jest.

> No to przeoczyłem. Oczekiwałbym, że wyja?nienie będzie jako odpowiedĽ na posta:
> http://niusy.onet.pl/niusy.html?t=artykul&group=pl.comp.objects&aid=38040519
> ty za? odpowiedziałe? dosłownie posta niżej:
> http://niusy.onet.pl/niusy.html?t=artykul&group=pl.comp.objects&aid=38041746
> ,a tego, co wyżej napisałem nie skomentowałe?. Uznałem, że mi się nie pomyliło.

Nie napisałem, bo nie miałem wtedy dostępu do środowiska, na którym mógłbym to
sprawdzić. Albo nie miałem czasu, już nie pamiętam. W każdym razie uzupełniłem
to później.

> Powiem, sk?d pomyłka: kiedy?, kiedy jeszcze robiłem sporo w C++ (może się
> od tego czasu co? zmieniło, cholera wi ...) miałem taki problem: załóżmy, że
> w naszym przykładzie klasa IPojazd nie jest abstrakcyjna - mamy już jak??
> gotow? implementację getNazwa(). Próba użycia tej metody z poziomu jakiejkolwiek
> innej metody w klasie Awionetka powodowała wyst?pienie błędu kompilacji: kompilator
> domagał się, by okre?lić, czy odwołujemy się do metody z klasy bazowej
> IPojazdPlywajacy, czy IPojazdLatajacy - mimo, że implementacja była
> jedna i ta sama w klasie bazowej IPojazd.

W C++ (pewnie w innych językach problem jest podobny) problem z wielorakim
dziedziczeniem objawia się w ten sposób, że jeśli dwie oddzielne klasy
dostarczają osobne definicje tej samej metody, to wtedy wywołanie tej metody w
klasie pochodnej jest niejednoznaczne.

Można by to wręcz w uproszczeniu określić w ten sposób, że metoda zdublowana w
klasie dziedziczonej jako "sibling" nie podlega dziedziczeniu. Rozwiązuje się
ten problem bowiem w podobny sposób: trzeba dostarczyć odpowiednią definicję
metody w klasie pochodnej i ewentualnie wywołać metody z klas bazowych jawnie.

Zresztą tu w grę wchodzi następna rzecz typowa dla obiektowości i niezbyt
sensownie możliwa do zrealizowania, gdy mamy wielorakie dziedziczenie: każda
metoda powinna mieć tzw. globalną definicję. Tzn. np. jeśli metoda nazywa się
"open" i ma otwierać plik, to w KAŻDYM istniejącym w systemie obiekcie ma
powodować otwarcie plik, niezależnie od tego, jakiej on jest klasy. Inaczej
mówiąc, nie może być w systemie dwóch metod o tej samej nazwie, których
intencją jest robienie zupełnie innych rzeczy. Np. przy takiej definicji
"open" nie może istnieć metoda "open", która "otwiera" okno.

> Oczywi?cie, sama maszyna wirtualna, a pewnie dokładniej schowany w niej JIT
> widzi i jedno i drugie bardzo podobnie - co ma sobie życie utrudniać. Ale
> ja nie nazwałbym tego "klas?".

Niby czemu?

> Jedno jest pewne - jak poczytasz o tym, to zauważysz, że jest jak mówię:
> programista klas na oczy nie widzi. Widzi tylko interfejsy.

Gówno mnie obchodzi, co widzi programista. Ważne, że klasa istnieje w
systemie.

> A projektant
> nie do?ć, że klas nie widzi, to nawet o nich nie my?li.
> I tu jest wła?nie pies pogrzebany.

A to już nie rozumiem, co ma do rzeczy.

W C++ programista tych klas też może "nie widzieć", np. przez to, że nie
ogląda plików z ich definicją.

Nie wiem, co ty właściwie tutaj chcesz pokazać jako "ficzer". Czy to, że
programista nie potrzebuje widzieć, czy to, że programista nie może widzieć?

> No nie ma klas, pane, nie ma. S? interfejsy, s? obiekty, s? zasady ich przetwarzania
> - stworzone na potrzeby projektu - ale klas nie widać ... Jak się uprzesz - to
> zobaczysz tę klasę ( o.getClass() ). Ale jej definicji już w swoim projekcie nie
> u?wiadczysz.

Ja w swoim projekcie też nie miewam klas np. ostream.

> > Nie w?tpię, że wła?ciwo?ci jakie dano klasom w Javie znacznie wykraczaj? ponad
> > to, co dano klasom w C++.
> >
> > Ale to naprawdę NIE MA NIC DO RZECZY.
> Ależ ma ;)

Nie ma. Rozmawialiśmy o ogólnym pojęciu interfejsu i klasy, a nie o tym, jakie
sztuczki można robić w Javie.

> > Jestem w stanie sobie wyobrazić bibliotekę, która z klasami robi takie obroty,
> > co Java.
> Czekałem na ten argument. Wisz pane, jakie biblioteki ja sobie potrafię
> w Javie wyobrazić ? Pane ... prawie mdleję, jak zaczynam ...

Nie mówimy o hipotetycznych bibliotekach, tylko o tych, które były
realizowane.

> S? już różne ciekawe - zdaje się, że próbuj? np. rozszerzyć powyższe
> o klasy - np. żeby obiekt konkretnej klasy można dynamicznie uzupełnić
> o dowolny interfejs, a by po tej operacji obiekt ten nie utracił
> informacji o tym jakiej jest klasy (standardowo informacji o klasie nie ma jak
> przepchn?ć).

Przecież to proste (jeśli jesteśmy w stanie podmieniać klasy). Podmieniamy po
prostu obiekt charakterystyczny klasy.

W C++ też można takie sztuczki robić. Ponieważ obiekt charakterystyczny jest
niczym innym jak obiektem, więc mając w bibliotece dynamicznej definicję
obiektu charakterystycznego klasy oraz metod tej klasy po prostu zamykamy
bibliotekę i otwieramy na nowo.

A interfejs spasujemy z obiektem i tak po UUID-zie.

> Pocieszę Cię tylko, że "różne biblioteki Java" potrafi? w runtimie generować
> bytekod - i robi? to na chwałę celów, które sobie stawiaj?.

Wiesz, biorąc pod uwagę wydajność Javy, jak miałbym się w takie rzeczy bawić,
to wykorzystałbym języki skryptowe.

> BTW. A widziałe? ty, jak działa debugger javy pod Eclipse ? :)
> Normalnie dynamicznie podmienia kod ;). Uruchamiasz sobie programik, wywaliło
> ci NullPointerExceptiona po naci?nięciu buttona na formatce, zagl?dasz do kodu,
> no tak - bug - poprawiasz, zapisujesz, wciskasz klawisz jeszcze raz i ... bingo ;).
> Potężne ?rodowisko uruchomieniowe z gigantyczn? formatk? ani drgnęło w czasie tej
> operacji a kod się podmienił. I nie s? to wielkie czary-mary - można to także
> z pewnym wysiłkiem, realizować programowo (definicja własnego ClassLoadera).

Wiesz, w Tk jeśli wystąpi ci błąd (nawet składniowy) w procedurze obsługi
jakiegoś przycisku, to dostajesz okienko z ostrzeżeniem, klikasz OK i
aplikacja dalej działa. Nie widzę również problemu, żeby podzielić skrypt na
część z implementacją (definicja handlerów) i część definicyjną (gdzie te
handlery się podpina). A potem ewentualnie spod programu wykonać "source".

Mając "klasy definiowane w bibliotece dynamicznej", mogę to samo robić też w
C++.

> > Dyskutowali?my nt. tego, czy interfejsem może być klasa czysto abstrakcyjna.
> > To była dyskusja czysto teoretyczna i odpowiedĽ tak samo powinna nadej?ć w
> > kategoriach abstrakcji.

> No to z teoretycznego punktu widzenia s? to różne rzeczy. Kiedy powstawał C++
> nie było mowy o interfejsach,

Fakt. Istniało już kilka języków obiektowych (C++ to 80-te lata) i żaden nie
miał pojęcia interfejsu (niech mnie bardziej zorientowani poprawią, oczywiście
:).

> > Rzecz jasna bez konkretnych przykładów rozmawiać się
> > nie da, ale przykłady maj? naprowadzać na wła?ciwe rozwi?zanie, a nie je
> > uzasadniać. Je?li je uzasadniaj?, to znaczy że rozwi?zanie nie mie?ci się w
> > granicach abstrakcji i jest zasadne tylko dla konkretnego specyficznego
> > przykładu. Do ogólnego twierdzenia to ma się wszakoż nijak: każdy sobie w
> > każdym konkretnym języku może nazwać klas?, obiektem, czy interfejsem, co też
> > mu się żywnie podoba, a zasady, jakimi się rz?dz? owe pojęcia i tak będ? dla
> > tych języków w najlepszym razie pod k?tem 30 stopni.
> E. A fe ... kto tak brzydko robi ?

Poza Smalltalkiem (nie wiem jak języki Lispopochodne, pewnie też) to chyba
każdy współcześnie używany język.

> > Tymczasem dylemat, czy interfejsem może być klasa czysto abstrakcyjna dotyczy
> > zupełnie innych kategorii i kontekstów.
> >
> > Po pierwsze, je?li już bierzemy pod uwagę dziedzinę wtórnej obiektowo?ci, to
> > jak najbardziej interfejs i klasa s? pojęciami różni?cymi się od siebie. Ale w
> > zasadzie na tym stwierdzeniu cała sprawa się kończy.
> >
> > Różnica jednak bierze się nie z faktu, że różni? się one sposobem realizacji,
> > tylko st?d, że różni? się one intencjami, dla których zostały one stworzone.

> No przesz o tym mówię.

No właśnie. Tyle że ich konstrukcja może być identyczna, niezależnie od tych
intencji. O tym już nie pomyślałeś?

> > To prawda, że klasy abstrakcyjne nie mog? i tak tworzyć obiektów i nadaj? się
> > tylko do tego, by tworzyć inne klasy. W takim podej?ciu nie okre?la się
> > szczególno?ci klasy czysto abstrakcyjnej jako szczególnego przypadku klasy
> > abstrakcyjnej, dopóki kto? nie wpadnie na pomysł, że z tej szczególno?ci można
> > w jaki? sposób skorzystać. Dopóki jednak mówimy o klasie, to nie mamy na my?li
> > nic innego, jak pojęcie uczestnicz?ce w hierarchii, tworz?ce inne klasy oraz
> > obiekty będ?ce ich instancjami.

> No wła?nie. A klasa obiektu proxy w javie nie spełnia tych wymagań
> - bo nie uczestniczy w hierarchii, nie tworzy innych klas ...

Jeśli tworzy obiekty, to jest klasą.
Z tą hierarchią to byłbym na twoim miejscu ostrożniejszy; podobno każda klasa
w Javie niejawnie dziedziczy po Object.

> A więc może
> lepiej nie nazywać jej klas? ? Ja jestem za. Proponuję uznać, że nie ma
> tu klasy, a s? tylko interfejsy. A interfejs klas? nie jest. Zapomniałe?
> o tym, że klasy maj? pola i metody

Klasy nie muszą mieć ani pól, ani metod, żeby być klasą. Tzn. z metodami to
nie jest tak jednoznacznie, ale pola nie są obowiązkowe. Klasy czysto
abstrakcyjne mogą mieć pola tylko teoretycznie (po cholere im pola, skoro nie
definiują niczego, co na nich operuje?).

> - zgodnie z najbardziej pierwotnymi założeniami OOP -

Klasa jest pojęciem wtórnym w obiektowości, więc nie bardzo pierwotnymi.

> dopiero potem mówimy o dziedziczeniu itp.

O dziedziczeniu mówimy przede wszystkim, jeśli mówimy o klasach.

> > Ponieważ wielorakie dziedziczenie jest sprzeczne z obiektowo?ci?, więc je?li
> > język dostarcza wielorakie dziedziczenie, to efektywnie pojęcie klasy jest w
> > tym języku jedynie REALIZOWANE za pomoc? odpowiedniej konstrukcji językowej,
> > być może zwanej klas?. Inaczej mówi?c, je?li stosujemy jednokrotne
> > dziedziczenie, to realizujemy pojęcie hierarchię klas. Je?li stosujemy
> > dziedziczenie wielorakie, to nie realizujemy pojęcia hierarchii klas. Proste.
> >
> > Je?li język za? nie dostarcza nam mechanizmu jawnie zwanego interfejsami, ale
> > dostarcza nam mechanizm mniej-więcej klas (w tym klas czysto abstrakcyjnych)
> > wraz z wielorakim dziedziczeniem, to możemy realizować zarówno klasy jak i
> > interfejsy w oparciu o te mechanizmy. I to wszystko.

> Dobra ... Jeszcze nie wiem, czy jestem za, ale wiem, że jeszcze nie jestem
> przeciw ... ;)

Aha, to oczywiście nie do końca wszystko.

Jeśli w danym języku interfejs zostanie zrealizowany za pomocą klasy czysto
abstrakcyjnej, to powstaje twór, który może pełnić rolę interfejsu i klasy
równocześnie.

Zgadzam się zatem ze stwierdzeniem "Interfejs nie jest klasą", jeśli mamy na
myśli intencje nadawane tym tworom.

Nie zgadzam się natomiast, że w sensie konstrukcji w jakimś języku
programowania nie może być klasy będącej przypadkiem równocześnie interfejsem.
Jeśli tak się zdarzy, to wtedy interfejs jest klasą (choć jest klasą tylko
czysto abstrakcyjną, co w praktyce oznacza obcięcie funkcjonalności takiej
klasy do minimum).


-- 
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethourhs(O)wp.pl>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"I am allergic to Java because programming in Java reminds me casting spells"
Technical Details
Message-ID: <dlqo6r$4td$1@kujawiak.man.lodz.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!news.task.gda.pl!news.man.lodz.pl!not-for-mail
References: <dlpte4$ol9$1@news.onet.pl> <dlqam1$711$1@kujawiak.man.lodz.pl> <dlqkmf$3lu$1@news.onet.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!news.task.gda.pl!news.man.lodz.pl!not-for-mail
From: Sektor van Skijlen <ethouris@pl.wp.spamu.lubie.nie.invalid>
Newsgroups: pl.comp.objects
Subject: Re: Czy interfejs to to samo co klasa czysto abstrakcyjna ?
Date: Sun, 20 Nov 2005 21:01:15 +0000 (UTC)
Organization: LODMAN - Metropolitan Area Network in LODZ, Poland
Lines: 247
Sender: Michal Malecki <sektor@zly.kis.p.lodz.pl>
Message-ID: <dlqo6r$4td$1@kujawiak.man.lodz.pl>
References: <dlpte4$ol9$1@news.onet.pl> <dlqam1$711$1@kujawiak.man.lodz.pl> <dlqkmf$3lu$1@news.onet.pl>
NNTP-Posting-Host: zly.kis.p.lodz.pl
Mime-Version: 1.0
X-Trace: kujawiak.man.lodz.pl 1132520475 5037 212.191.89.2 (20 Nov 2005 21:01:15 GMT)
X-Complaints-To: abuse@man.lodz.pl
NNTP-Posting-Date: Sun, 20 Nov 2005 21:01:15 +0000 (UTC)
User-Agent: tin/1.6.2-20030910 ("Pabbay") (UNIX) (SunOS/5.9 (sun4u))
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit