Egyszeres vagy többszörös öröklődés

Fórumok

A CCC objektumrendszerében többszörös öröklődés van. Érdekelne, ki mit gondol, miért van az újabb nyelvekben (Jáva, C#, D) egyszeres öröklődés?

Hozzászólások

egyrészt a diamond inheritance kiküszöbölése miatt

class a(object)
method hopp {||qout("hopp")}

class b(a)

class c(a)

class d(b,c)

function main()
dNew():hopp

Ez egy működő program, kiírja, hogy "hopp". A liststruct metódus kiírná, hogy a d osztály hopp metódusa az a osztályból öröklődik. Ha ez nem felel meg, egyszerűen felül lehet definiálni. Emiatt miért kéne lemondani a többszörös öröklődésről?

--
CCC3

class a(object)
method hopp {||? "a.hopp"}

class b(a)
method hopp {||? "b.hopp"}

class c(a)
method hopp {||? "c.hopp"}

class d(b,c)

function main()
local d:=dNew()

d:hopp()

return NIL

eredménye: b.hopp

De ha: class d(c,b), akkor c.hopp az eredménye neki.
Hát, nemtom, jó ez vajon? Én még a büdös életbe' nem használtam többszörös öröklést CCC-ben, sose volt rá szükségem. Szerintem az mrev által találóan "tudálékos"-nak nevezett nyelvek sajátja az, hogy minden mindig mindenhol legyen objektum, sőt még objektumabb, és ezért jönnek elő ilyen gondok. Én általában csak azt teszem objektummá, ami "kéri", hogy azzá tegyem, így meg nem jön elő a kérdés. De szerintem mesterségesen megszüntetni az egyébként működő többszörös öröklést CCC-ben nem érdemes.

w

Az igaz, hogy nem túl gyakori, de van példa a többszörös öröklésre. A GTK csatolóban pl. kiváló szolgálatot tesz. Eszem ágában sincs megszüntetni.

A téma szándékosan provokatív. Szerintem tudálékos emberek rosszul terveznek meg nyelveket, amit aztán programozók ezrei sínylenek. Egyébként van olyan nézet is, hogy a Jáva és a C++ szándékosan van elkúrva, nehogy a programozók kifogyjanak a munkából. Persze, ha levágom a lábamat, akkor nem lesz lúdtalpam. Ha megszüntetem a számtípusokat, akkor nem lesz nullával osztás, meg hasonlók. Kb. ennyi értelmét látom a "diamond inheritance"-tól való félelemnek. Más nézet?

--
CCC3

Engem erdekelne valami technikai magyarazat is a diamond inheritancen kivul, konkretan vajon ez hol okozhat problemakat a gyakorlatban?

Azt azert ketlem, hogy barmit is direkt rosszul terveztek a C# es Java nyelveken. (Mar csak azert is, mert egy nyelv tervezese az nem annyibol all, hogy valami okostojas hasara ut es azt mondja, "na igy kb. jo lesz"..)

Nem lehet hogy inkabb a nehezebben felfoghato orokles helyett inkabb a tartalmazasra akarjak rabirni a fejlesztoket? Szerintem a Java-nak inkabb az a filozofiaja, hogy egy osztaly egy dologgal foglalkozzon. Ha pedig kombinalt tudasra van szukseg a feladatahoz, akkor implementalja a szukseges interfeszt, es az ala bedolgozo osztalyokat meg tartalmazza.
Gyakran az oroklesbe latunk bele olyan dolgokat, amikor a tartalmazas is tokeletesen jo, raadasul konnyebben emesztheto.

Egy nyelv elterjetseget nem csak az hatarozza meg szerintem, hogy mennyire expressziv, hanem az is, hogy mennyire konnyu hasznalni, mekkora a hibalehetoseg a hasznalat soran, mennyire konnyu hibat keresni, milyen a fejlesztokornyezet, stb.

Pl. vannak olyan meta-nyelvek, amiben konnyu szerrel lehet magat az osztaly,objektum, oroklodes, adatrejtes, stb. fogalmat definialni es onnantol kezdve az is egy objektumorientalt nyelv lesz, meg se elterjedt ez a tipusu megkozelites.. Talan pont azert, mert van egy hatar, amit egy atlagos fejleszto "ep esszel fel tud fogni" es szerintem a Java es C# bonyolultsaga ezt az optimumot celozza meg, nem pedig a maximalis expresszivitast.

Python-ban is többszörös öröklődés van - ráadásul futásidőben változtatható (mint minden :) ) - MixIn osztályoknál (is) hasznos!

1. Sokkal nehezebb forditot irni hozza. JIT compilerek idejen kulonosen fontos szempont.
Pl. ne feledd, hogy tobbszoros oroklodesnel az objektumban ket, elkulonitett helyet kell hagyni a ket kulonbozo osztalybol jovo adattagoknak (az atfedeseket elkerulendo). Igen am, de ez azt jelenti, hogy nem fix memoriacimen kezdodnek az adattagok, tehat kell egy kulon pointer-tabla a kulonbozo osokbol szarmazo adatteruletek cimzesehez. Es ha aztan az objektumot at-castolod egyik osere, akkor tudni kell, hogy melyik adattag-blokkot kell cimezni, tipustol fuggoen, ugye. Aztan ha = operatorral erteket adsz, kulon ugyelni kell a masolasnal. Es akkor meg csak az adattagokrol beszeltem, fuggvenyekrol nem.

Nem veletlen, hogy c++ forditokban meg ma is gyakori a hiba, mig a c forditok mar evtizedek ota stabilak.

Ha bovebben erdekel a tema, szerezz be egy jobb c++ konyvet (a strosoup-fele jo kezdet, vagy magyarul is van egy par, amelyik elmagyarazza, hogy milyen feature-t hogyan valosit meg a c++ fordito (stack/memoria-muveletek szintjen), na abbol meg fogod erteni, mennyire bonyi is a dolog.

2. Kezdo programozokat (akik minden programnyelv derekhadat adjak) megzavarja/nem ertik/stb, marpedig mindenki kezdokent indul egy uj nyelvvel. Ez egyebkent a hivatalos magyarazata a JAVA eseten a mindenfele c++ feature elhagyasanak.

3. Igazabol nagyon ritkan van ra szukseg. Tipikusan egyszerubb is megerteni/attekinteni az objektum-hierarchiat, ha hanyagolod a kerdest.

"de ez azt jelenti, hogy nem fix memoriacimen kezdodnek az adattagok"

Emiatt van a GObject-ben is csak egyszeres öröklődés. De erre azt lehet mondani, hogy a készítő lusta volt rendesen megírni a többszörös öröklődést, ezért az eredmény funkcionálisan hiányos. Éppen a GTK-ban (GObject alkalmazás) bőven volna helye a többszörös öröklődésnek. Helyette interfészeket kényszerül használni.

Szerintem a C++-nak nem a többszörös öröklődés a baja, hanem az agyonbonyolított szabvány, amiben éppen Stroustrup a bűnös. Ez az ember 1000 oldalas C++ könyvet írt, ahelyett, hogy olyan nyelvet talált volna ki, amit 100 oldalon is le lehet írni.

Lehet, hogy egyes nyelvekben a többszörös öröklődés elbonyolítja a fordítót. A Python és a CCC nem ilyenek. A CCC fordítója 20 sorral sem volna rövidebb többszörös öröklődés nélkül. Tény, hogy fellépnek többértelműségek. Ezekre kell valamilyen egyszerű feloldási szabály. A Pythonban/CCC-ben depth first searching van, a Python az utolsónak talált definíciót tartja meg, a CCC az elsőt (mindegy). Minden olyan esetben, amikor ez a default feloldás nem felel meg, felüldefiniálással kell orvosolni a gondot.

--
CCC3

Teljesen mas a java interfesz implementacioja. Ott ugye minden fugggveny virtualis. Tehat van egy objektumod, amirol tudod, hogy milyen interfeszeket valosit meg. Ha meghivjak vmelyiket, egyszeruen nev szerint kikeresi a virtualis fgv tablabol (strcmp+hash-el), es odaugrik. Azert ez a megoldas nem hasonlithato a c++-fele tobbszoros oroklodeshez. :)

A dolgok legyenek minél egyszerűbbek. Egy egyszerűnek megtartott többszörös öröklődés, egyszerűbb, mint az egyszeres öröklődés plusz interfészek. A többszörös öröklődésnek kétségtelenül vannak problémái, ezt azonban nem lehet interfészekkel kikerülni, mert azoknál ugyanolyan ellentmondások lépnek fel.

A CCC-ben minden metódus public, minden öröklődés virtuális (C++ terminológiával), a többszörösen örökölt adattagok nem többszöröződnek. Amikor ezek a hibák nem javíthatók ki felüldefiniálással, akkor nem alkalmazható a többszörös öröklődés, hanem mást kell csinálni, pl. beágyazást. És akkor még mindig nem állunk rosszabbul, mint egy egyszeres öröklődésű nyelv, amiben ez a kiindulás. Szerintem ez egy praktikus álláspont.

A CCC-ben az objektum-metódus párosítás futásidőben történik, emiatt az interfész technika magától működik, anélkül, hogy ezért bármit tenni kéne. Az már igaz, hogy ezt a fordító nem képes előre ellenőrizni.

--
CCC3

C++ nincs elszurva, egyszeruen mas szempontok alapjan terveztek.. a c az elodje, amit ugy terveztek, hogy amellett, hogy kenyelmes (az akkori nyelvekhez hasonlitva), eszmeletlen hatekony forditokat lehet hozza csinalni, ha valaki esszel kodol..
A c++ is ilyen: nem minden alapbol virtual, de ha valamihez az a jo, ele lehet irni..
Nem kenyszeriti ra senkire az alapelveit, nem kotelezo STL-t, template-eket, funktorokat, egyaltalan objektumokat hasznalni.. mindenki eldontheti, hogy meddig akar elmenni..
Hasznalhat akar fuggvenyre mutato pointert is, ha azt szeretne inkabb.. lehet tobbszorosen orokoltetni, de megvalosithato az interface megfeleloje.. mellesleg pont ez teszi bonyolultta, hogy a kenyelmi szintet es a hatekonysagot az ember maganak barmilyen szintre beloheti..

A Java-ban mindent az alapelvei ele helyeztek (peldaul ez a "minden ojjektum" hulyeseg).. kitalaltak egy nyelvet, irtak hozza forditot, futtato kornyezetet, meg mindent.. a tobbszoros orokles valoszinu meghaladta volna a kepessegeiket, ezert inkabb utolag kitalaltak egy ideologiat, hogy miert is nem kell..
kicsit olyan, mint amikor az egyik ovodas magyarazza a masiknak, hogy o direkt hasra akart esni, mert....

---------------------
"Monumentalis gondolataim manifesztacioi - melyek mondatok formajaban realizalodnak - limitalt mentalis kepessegeid szamara nem mind akceptabilisak. Dialogusunk kontinuitasa igy megszakad. Nem jon letre az argumentumok szintezise."

ez az amit a fenti hozzaszolasomban probaltam elmagyarazni. Ez nem jo erv, hogy hat a Java-soknak meghaladja a kepessegeit, meg hogy ok nem gondoltak ra (biztos hulyek szegenyek..)

Ennyi erovel azt is mondhatnam, hogy a C a "legjobb nyelv". Hiszen C-ben is leimplementalhatok egy komplett osztaly-objektum-oroklodes stb. semat es ugyanazt (vagy akar meg tobbet is) meg tudok benne csinalni mint C++-ban.

A C es C++ nyelv semmivel sem erosebb, nem lehet nagyob kifejezo ereju kodot irni az egyikben mint a masikban..

Lehet hogy valaki C++ alatt kodol (es mivel eppen zseni programozo), ezert ki tudja hasznalni a C++ adta nehany extra lehetoseget es tenyleg jobb es szebb lesz mint Java-ban. Ellenben mondjuk egy atlagos tehetsegu programozo, lehet hogy jobban teszi ha C#-ban kodol, mert kevesebb hibalehetoseget hagy maganak, konnyebb a hibakereses, stb.

Azt az allitast, hogy egy atlagos tehetsegu programozo Java/C#-ban jobb kodot ir mint C++-ban, azt hiszem minden nyitott szemmel jaro fejleszto meg fogja erositeni.

Az egesz dolog arra emlekeztet, mint amikor meglat valaki egy suzukit az utcan es kijelenti, hogy hat igen, szegeny suzuki-nak csak olyan mernokei vannak, akik csak ezt tudtak csinalni, ennyi tellett a kepessegeikbol..