Upload
gaston
View
33
Download
0
Embed Size (px)
DESCRIPTION
Kevätlukukausi 2010 Jyväskylän yliopisto Tietojenkäsittelytieteiden laitos Markku Sakkinen. Komponenttipohjainen ohjelmistotekniikka (TJTSS56) Osa 6. Perinteisissä oliokeskeisissä ohjelmistokehyksisssä laajentaminen perustuu ensi sijassa periytymiseen - PowerPoint PPT Presentation
Citation preview
Komponenttipohjainen ohjelmistotekniikka (TJTSS56)
Osa 6
Kevätlukukausi 2010Jyväskylän yliopisto
Tietojenkäsittelytieteiden laitosMarkku Sakkinen
Polymorfisuus (jatkoa)Riippumattoman laajennettavuuden ulottuvuuksia
Szyperski, kohta 6.9
Perinteisissä oliokeskeisissä ohjelmistokehyksisssä laajentaminen perustuu ensi sijassa periytymiseen
• Kehyksen luokille (yleensä abstrakteille) määritellään aliluokkia.• Jos jokin kehyksen abstraktio ei sovi rakennettavaan sovellukseen
tarpeeksi hyvin, aliluokat eivät toteuta korvattavuutta eli periytyminen ei ole aitoa erikoistamista.
• Tämä on mahdollista, koska toteutuksen perintä nykyisissä kielissä ei vaadikaan aliluokilta yliluokkien mukaista semantiikkaa.
Perinteiset ohjelmistokehykset ovat vain kehitysaikaisia ”olioita”, jotka eivät ole toimivassa ohjelmistossa erillisinä näkyvissä.
• Huomattavia ongelmia periytymisen kyseenalaisesta käytöstä tulee vasta sitten, jos ohjelmisto haluttaisiin siirtää kehyksen uuteen versioon.
• Kehys ja siihen perustuva ohjelmisto eivät ole toisistaan riippumattomasti laajennettavia.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 63. 3. 2010 2
Riippumattoman laajennettavuuden ulottuvuuksia (jatkoa)Riippumattomasti laajennettavissa komponenttijärjestelmissä tilanne on
hyvin toisenlainen.• Jokaisessa komponentissa täytyy varautua siihen, että sen
käyttämiä tai palvelemia komponentteja vaihdetaan jopa ajon aikana.
• Sopimusten tarkka toteuttaminen on välttämätöntä.• Tarvitaan selvät määritelmät siitä, mitä ja miten voidaan laajentaa.
Jokaista tällaisen järjestelmän piirrettä, jota voidaan laajentaa erikseen, kutsutaan (riippumattoman) laajennettavuuden ulottuvuudeksi (dimensioksi).
• Olisi hyvä, että eri ulottuvuudet olisivat ”ortogonaalisia”.• Muuten voidaan samanlainen vaikutus saada laajentamalla eri
ulottuvuuksissa.• Tärkeämpää on kuitenkin, että laajentamismahdollisuudet ovat
riittävät ohjelmiston evoluutiotarpeisiin nähden.• Yleensä täysi ortogonaalisuus ei ole mahdollinen.• Esim. jos järjestelmässä on laajennettavat abstraktiot olioiden
sarjallistamiselle ja säilyvyydelle, niillä on luultavasti jotain yhteistä.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 63. 3. 2010 3
Riippumattoman laajennettavuuden ulottuvuuksia (jatkoa)Riippumattomasti laajennettavassa järjestelmissä täytyy olla jokin
perusrakenne, jota sitten laajennetaan.• Eri laajennusulottuvuuksien välisiä rajapintoja kutsutaan
pullonkaularajapinnoiksi (bottleneck interfaces).• Erityisesti näiden rajapintojen täytyy olla muuttumattomia.• Huonosti suunnitellussa komponenttikehyksessä eri ulottuvuuksiin
kuuluvat laajennuskomponentit voivat tarvita muitakin yhteyksiä toisiinsa.
Ainokaiskonfiguraatio (singleton configuration)• Joskus vaaditaan, että järjestelmässä on täsmälleen yksi tai
enintään yksi tiettyä ulottuvuutta laajentava komponentti.• Esimerkki voisi olla turvallisuudenhallitsin.Rinnakkaisiksi laajennoksiksi sanotaan sellaisia komponentteja, jotka
laajentavat samaa ulottuvuutta.Ortogonaalisiksi laajennoksiksi sanotaan sellaisia komponentteja, jotka
laajentavat eri ulottuvuuksia.Myös rekursiivinen laajentaminen on mahdollista.• Jokin komponentti voi itse olla myös komponenttikehys.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 63. 3. 2010 4
Evoluutio vastaan rajapintojen ja sopimusten muuttumattomuus
Szyperski, kohta 6.10
Sopimus (rajapinta ja sen semantiikan määrittely) yhdistää riippumattomasti kehittyviä palvelimia ja asiakkaita.
• Kun sopimus on julkaistu, sitä ei pitäisi enää muuttaa.• Palveluntarjoaja voi lakata tarjoamasta jotakin sopimusta, mutta
se menettää silloin ne asiakkaat, jotka tarvitsevat juuri tämän sopimuksen mukaisia palveluja.
• Palveluntarjoaja ei voi muuttaa sopimuksen spesifikaatiota (semantiikan määrittelyä).
• Asiakas ei voi muuttaa omaa sopimuksen tulkintaansa, tai sille voi aiheutua virheitä palvelun käytössä.
• Jotta sopimuksesta voidaan edes keskustella, siihen on pystyttävä viittaamaan yksikäsitteisesti.
• Yleensä käytetään rajapinnan nimeä viitaamaan koko sopimukseen.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 63. 3. 2010 5
Evoluutio vastaan rajapintojen ja sopimusten muuttumattomuus (jatkoa)
Jos sopimusta kuitenkin muutetaan, muutos voi olla kahta laatua:• Syntaktinen: rajapinta muuttuu (esim. jonkin metodin parametrien
järjestys).• Semanttinen: spesifikaatio muuttuu.• Monet muutokset koskevat tietysti sekä syntaksia että
semantiikkaa, esim. uuden metodin lisääminen.Olio-ohjelmoinnissa palvelinluokka ”hallitsee” sopimusta.• Puhutaan ”särkyvän yliluokan” (fragile base class) ongelmasta.
Sopimusten evoluutio on mahdollista silloin, kun ne ovat vain jonkin projektin tai organisaation sisäisiä.
• Kun tehdään muutos, voidaan tarkistaa kaikki asiakkaat ja palvelimet, joihin se vaikuttaa.
Joissakin komponenttijärjestelmissä sallitaan rajapintojen versiointi.• Entiset asiakkaat voivat käyttää vanhaa versiota, vaikka
uudempikin on tarjolla.• Esim. entisessä IBM:n SOMissa (System Object Model) uudessa
versiossa rajapintaan sai vain lisätä uusia metodeja.Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 3. 3. 2010 6
Evoluutio vastaan rajapintojen ja sopimusten muuttumattomuus (jatkoa)
Sopimus voi olla määräaikainen.• Varsin luonnollista, jos sopimukseen liittyy lisensiointi.• Asiakkaat tietävät, että sopimuksen mukaiset palvelut voivat
loppua määräpäivänä.• Palveluntarjoajat tietävät, että velvollisuus tarjota palveluja
loppuu määräpäivänä.• Sopimuksen voimassaoloa entisellään voidaan päättää jatkaakin.• Voidaan myös tehdä uusi, muunnettu sopimus.
Korkeamman tason määräykset voivat vaatia muutoksia sopimuksiin, kuten lainsäädäntö ym. liike-elämän sopimuksiin.
• Kansalliset ja kansainväliset standardit.• Määräävässä asemassa oleva yhtiö.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 3. 3. 2010 7
Muita polymorfismin muotoja
Monimetodit (multimethods, multiple dispatching)• Joissakin oliokielissä metodinkutsun dynaaminen sidonta voi
perustua myös parametrien eikä vain kohdeolion todellisiin (dynaamisiin) tyyppeihin.
• Helpottaa asiakkaiden ohjelmointia monissa tilanteissa.• Toisaalta aiheuttaa sekä periaatteellisia että toteutuksellisia
ongelmia.
Kuormitus (overloading)• Monissa oliokielissä (esim. C++:ssa, Javassa ja C#:ssa) ja muissa
kielissä.• Samalla nimellä voi olla useita eri metodeja (samassa luokassa),
jotka erotetaan toisistaan parametrien tyyppien perusteella.• Oikea vaihtoehto tunnistetaan käännösaikana (salakavala ero
monimetodeihin).• Kutsutaan joskus ad hoc -polymorfismiksi.• Metodeilla olisi hyvä olla samanlainen semantiikka.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 3. 3. 2010 8
Muita polymorfismin muotoja (jatkoa)Geneerisyys (genericity)• Atk-sanakirja suosittelee myös termiä ”malli-” adjektiivin
”geneerinen” vastineeksi.• Myös ”parametrinen polymorfisuus” (parametric polymorphism).• Luokalla (tai pakkauksella tms.) voi olla muodollisia geneerisiä
parametrejä (malliparametrejä).• Varsinainen luokka (tms.) syntyy vasta instantioimalla
(generoimalla) geneerinen luokka (luokkamalli) sopivilla todellisilla parametreillä.
• Instantiointi tapahtuu käännösaikana.• Geneeriset parametrit ovat yleensä luokkia (tai muita tyyppejä).• Esim. Adassa ja C++:ssa myös tietotyyppien vakioarvot ovat
mahdollisia.
Syntaktinen geneerisyys• C++:ssa geneeriset luokat ja aliohjelmat (templates) ovat
makrojen kaltaisia.• Mallin tasolla kääntäjä voi todeta vain syntaktiset virheet.• Kelvollisuus (mm. tyypitys) ja semantiikka selviävät vasta kutakin
instantiointia käännettäessä.Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 3. 3. 2010 9
Muita polymorfismin muotoja (jatkoa)
Semanttinen geneerisyys• Jo mallilla (geneerisellä luokalla tms.) on yksikäsitteinen
semantiikka, jonka kääntäjä selvittää.• Geneerisen koodin pitää olla kelvollista kaikille mahdollisille
todellisille parametreille.• Ellei jollekin muodolliselle parametrille määritellä rajoitteita
(constraints), sen käyttömahdollisuudet ovat vähäiset.• Sopii ensi sijassa säiliö- ja kokoelmaluokille.
• Oliokielissä tavallisin rajoite on jokin rajaluokka, jonka jälkeläinen todellisen parametrin pitää olla (mm. Eiffelissä ja Javassa).
• Joissakin kielissä (mm. Eiffelissä ja Javassa) voidaan kääntää jo geneerinen luokka eikä jokaista generoitua luokkaa erikseen.
• Tämä sekä edellyttää joitakin rajoituksia parametreille että aiheuttaa joitakin rajoituksia generoitujen luokkien käytölle.
Perhepolymorfisuus (family polymorphism)• Erik Ernstin esittelemä (ECOOP 2001:ssä) uusi lähestymistapa,
joka pyrkii yhdistämään periytymisen ja geneerisyyden edut.• Vaikuttaa hyvin lupaavalta varsinkin komponenteille.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 3. 3. 2010 10
Perinnän korvaaminen koostamisellaSzyperski, luku 7
Tässä luvussa tutkitaan perinnän erilaisia merkityksiä oliokielissä ja sitä, missä määrin toteutuksen perinnän sijasta olisi parempi käyttää koostamista (composition).
• Periytymistä voidaan pitää luokkien välisenä koostamisena, joten tässä verrataan luokkien ja olioiden koostamista toisiinsa.
• Erityisesti käsitellään särkyvän yliluokan ongelmaa.• Kurinalainen periytyminen (disciplined inheritance) voi estää
joitakin ongelmia.• Juuri tuo oli minun ECOOP’89:ssä julkaistun artikkelini nimi.
• Siinä pyrin tarkastelemaan perintään koostamisen erikoistapauksena.• Työnimenä oli ”Inheritance considered harmful”.
Periytymisen kolme tärkeintä aspektia (ainakin Szyperskin mielestä):• Toteutuksen perintä eli aliluokkasuhde (subclassing)• Rajapinnan perintä eli alityyppisuhde (subtyping)• Korvattavuus (substitutability)
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 3. 3. 2010 11
Perinnän korvaaminen koostamisella (jatkoa)
Useimmissa oliokielissä toteutuksen ja rajapinnan perintä ovat erottamattomasti yhdessä.
• Pelkkää rajapintaa ei voida periä sellaisesta luokasta, jossa on yhtään toteutusta mukana.
• On joitakin kieliä, joissa perintä ja alityyppisuhde on erotettu toisistaan.
• Erityiset rajapinnanmäärittelykielet (esim. COMissa ja CORBAssa) eivät ota ollenkaan kantaa toteutukseen.
• Joissakin kielissä on mahdollista kertoa, että aliluokka perii yliluokalta vain toteutuksen.
• C++:ssa yksityinen perintä – jopa oletuksena!• Mahdollisuus on lisätty äskettäin Eiffeliin (non-conforming inheritance).
Korvattavuus on näistä ominaisuuksista vaikein määritellä ja toteuttaa.• Useimmissa kielissä se tavallaan oletetaan, mutta jää ohjelmoijan
vastuulle.• C++:ssa ja Eiffelissä aliluokan olio ei voi korvata yksityisesti tai
”mukautumattomasti” perityn yliluokan oliota.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 3. 3. 2010 12
Perinnän vivahteitaOsittain Szyperski, kohta 7.2
Moniperintä (multiple inheritance)
Kaksi toisistaan riippumatonta jakoa (ainakin).• Peritäänkö rajapinta, toteutus vai molemmat?• Onko perittävillä luokilla tai rajapinnoilla yhteisiä esivanhempia
(haarautuva moniperintä – fork-join, repeated, diamond inheritance) vai ei (riippumaton moniperintä – independent multiple inheritance) ?
Tärkein lähestymistapojen jako: käsitelläänkö kunkin yliluokan uusia (ei perittyjä) ominaisuuksia yhtenä kokonaisuutena (alioliokeskeinen) vai ei (atribuuttikeskeinen)?
• Useimmat moniperintäkielet noudattavat atribuuttimallia – myös Java rajapintojen periytymisessä.
• Puhtaassa atribuuttimallissa samaistetaan eri yliluokista perityt atribuutit ja metodit, jos niillä on sama nimi ja tyyppi (tai kutsumuoto).
• Eiffelissä samaistaminen tapahtuu vain haarautuvassa perinnässä, ja se voidaan estää uudelleennimeämisellä.
• Tärkein alioliomallia noudattava kieli on C++.Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 4. 3. 2010 13
Perinnän vivahteita (jatkoa)
Atribuuttipohjaisen lähestymistavan lisäjako: otetaanko huomioon koko periytymisrakenne (verkkoperiaate) vai pelkästään välittömät yliluokat (lineaarinen periaate)?
• Tällä kurssilla pidämme oletuksena verkkoperiaattetta, jota ainakin useimmat staattisesti tyypitetyt kielet noudattavat.
• Seuraavassa esitetään lineaarisen lähestymistavan erikoisominaisuuksia (hieman yksinkertaistaen).
• Riippumattomalla ja haarautuvalla moniperinnällä ei ole eroa.• Yleensä perintä linearisoidaan niin, että luokan määritelmässä
mainittujen yliluokkien järjestys on merkitsevä.• Samannimisistä ominaisuuksista peritään automaattisesti vain se,
jonka luokka on järjestyksessä ensimmäisenä.• Voi aiheuttaa yllättäviä tilanteita mutkikkaissa
periytymisverkoissa.• Vallitseva (tai ainakin suosittu) Lisp-pohjaisissa oliokielissä:
Flavors, CLOS (Common Lisp Object System) ym.• Näissä kielissä ei yleensä ole staattista tyypitystä.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 4. 3. 2010 14
Perinnän vivahteita (jatkoa)Riippumaton moniperintä on haarautuvaa yksinkertaisempi tapaus.• Useimmissa oliokielissä on kaikkien luokkien yhteinen yliluokka,
joka täytyy jättää ottamatta huomioon, jottei kaikkea moniperintää tarvitsisi käsitellä haarautuvana.
• Atribuuttikeskeisessä periaatteessa vahingossa tapahtuva ominaisuuksien samaistuminen voi kuitenkin aiheuttaa salakavalia virheitä.
• Uudelleennimeämisen mahdollisuudella voitaisiin sekä korjata tuollaisia tilanteita että sallia erinimistenkin perittyjen ominaisuuksien samaistaminen.
• Toisaalta moniperintä ei ole sallittu, jos perittävien samannimisten ominaisuuksien tyypit tai kutsumuodot ovat erilaisia – paitsi jos kuormitus on mahdollinen.
• Javan rajapintojen moniperintä ei ole sallittu, jos perittävien samannimisten metodien kutsumuodoissa eroaa vain tulostyyppi.
• Jos rajapinta käsittää myös esi- ja jälkiehdot, niiden välillä voi hyvin helposti olla ristiriitoja.
• Lineaarisessa moniperinnässä samannimisten ominaisuuksien ristiriidat eivät vaikuta, koska vain ensimmäinen niistä otetaan huomioon.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 4. 3. 2010 15
Perinnän vivahteita (jatkoa)Haarautuva moniperintä on vaikeampi ja mielenkiintoisempi tapaus.• Nimitys ”vinoneliöperintä” (diamond inheritance) johtuu
luonnollisesti luokkakaaviosta.• Oli yhtenä aiheena vuoden 1989 ECOOP-artikkelissani.• OOPSLA 2009 -konferenssissa oli jälleen yksi artikkeli, jossa
esitettiin uutta kielen mekanismia tähän.• Ja taistelu jatkuu…Perusongelma: tuleeko kahta eri kautta peritystä ominaisuudesta tai
alioliosta aliluokassa yksi vai kaksi?• Atribuuttikeskeisessä perinnässä aina yksi, ellei
uudelleennimeäminen ole mahdollista.• Alioliokeskeisessä perinnässä monistaminen (kaksi alioliota) on
helpompi toteuttaa kuin jakaminen (yksi aliolio).• C++:ssa oletus, jakaminen virtual-määreellä.• Jakavan ja monistavan perinnän yhdistelmät voivat C++:ssa johtaa varsin patologisiin luokkarakenteisiin.• Niiden vuoksi ”virtuaalisen” yliluokan tyyppistä viitettä ei voida muuntaa minkään aliluokan tyyppiseksi – yksinkertaisissakaan periytymisrakenteissa.
• Jakaminen vastaa paremmin periytymisen käsitteellistä merkitystä, varsinkin jos halutaan korvattavuutta.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 4. 3. 2010 16
Perinnän vivahteita (jatkoa)
Tilanne on yksinkertaisin, kun peritään vain rajapinta.• Mikäli perinnässä sallitaan metodin parametrien tai tuloksen
tyypin tai esi- ja jälkiehtojen uudelleenmäärittely, voi kuitenkin aiheutua ristiriita, joka estää jakavan moniperinnän.
Atribuutin (aliolioperiaatteessa koko aliolion) haarautuva perintä:• Jakava perintä on yhtä ongelmaton kuin rajapinnan tapauksessa.• Monistavassa perinnässä korvattavuus kärsii: jos aliluokan oliota
käsitellään yhteisen yliluokan oliona, kumpi atribuutti valitaan?
Toteutetun metodin haarautuva perintä:• Jo jakavassa perinnässä tulee pieni ongelma, jos
uudelleenmäärittelyjen takia perittävinä on kaksi eri toteutusta.• Useimmat kielet vaativat tällöin uudelleenmäärittelyn aliluokassa.• Perittyjen metodien kutsuminen (super) voi helposti aiheuttaa
alkuperäisen metodin kutsumisen kahteen kertaan. • Monistavassa perinnässä on lisäksi sama ongelma kuin
atribuutilla.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 4. 3. 2010 17
Perinnän vivahteita (jatkoa)
Lisukkeet (sekoitteet?) (mixins)
Jo Flavors-kielessä (Moon, OOPSLA’86) otettiin käyttöön lisukeluokat.• Tarkoitettuja täydentämään muita luokkia, eivät voi tuottaa
ilmentymiä yksinään.• Luonnehdittu myös ”abstrakteiksi aliluokiksi”, mutta niistä
peritään ainakin ensi sijassa toteutusta eikä rajapintaa.• Dynaamisesti tyypitetyssä kielessä, jossa noudatetaan lineaarista
moniperintää, lisukkeiden käyttöön tarvitaan hyvin vähän byrokratiaa.
• Uusi luokka voi periä mielivaltaisen joukon tavallisia ja lisukeluokkia.
• Jos luokka perii tai toteuttaa itse ainakin kaikki ne metodit, joita sen omat ja perityt metodit kutsuvat kohdeoliolle, se on kelvollinen konkreetti luokka.
• Dynaamisessa kielessä tätäkään ei yleensä voida todeta staattisesti; tarkoittaa, että virhettä ”method not found” ei tapahdu ajon aikana.
• Järkevä semantiikka ei tietenkään toteudu automaattisesti.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 4. 3. 2010 18
Perinnän vivahteita (jatkoa)Esimerkki: Kuvitellaan, että olisi olemassa laajennettu kieli Mixin Java (pitemmälle vietynä kuin kirjassa). Määritellään alkeellinen ikkunaluokka lisukeluokkien avulla. Ensin kolme rajapintaa ikkunan eri aspekteille:
interface DrawWindow { void drawWindow ();}
interface DrawBorders { void drawBorders (); void handleMouse (Event ev);}
interface DrawContents { void drawContents (); Rect getVisibleSection (); Rect getContentsBox (); void scrollTo (Rect newVisible);}
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 5. 3. 2010 19
Perinnän vivahteita (jatkoa)Sitten koko ikkunan rajapinta (COMissa tämä voisi olla kategoria):
interface Window extends DrawWindow, DrawBorders, DrawContents { }
Sitten lisukeluokka kullekin suppealle rajapinnalle:
mixin class StdWindowShell implements DrawWindow requires DrawBorders, DrawContents { void drawWindow () { drawBorders (); drawContents (); }}
mixin class TextWindowContents implements DrawContents void drawContents () { . . . } Rect getVisibleSection () { . . . } Rect getContentsBox () { . . . } void scrollTo (Rect newVisible) { . . . }}Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 5. 3. 2010 20
Perinnän vivahteita (jatkoa)mixin class MotifWindowBorders implements DrawBorders { requires DrawContents { void drawBorders () { . . . // draw title bar Rect visible = getVisibleSection (); Rect total = getContentsBox (); . . . // draw scroll bars } void handleMouse (Event ev); . . . if ("scroll bar thumb moved") { . . . // compute new visible region scrollTo (newVisible); } . . . }}
Ainakin luokassa TextWindowContents täytyy tietysti olla myös joitakin atribuutteja, jotta sen metodit voidaan toteuttaa.
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 5. 3. 2010 21
Perinnän vivahteita (jatkoa)
Komponenttipohjainen ohjelmistotekniikka (Markku Sakkinen) – Osa 6 5. 3. 2010 22
Lisukeluokan lauseella requires kerrotaan, mitä rajapintoja se vaatii jokaisessa sen perivässä (suoraan tai välillisesti) konkreetissa luokassa olevan toteutettuina.• Kuten komponentin vaatimat rajapinnat.• Tällaista ei tarvita dynaamisissa kielissä.
Lopuksi voidaan luoda konkreetti tavallinen luokka yksinkertaisesti perimällä kaikki lisukkeet.• Yleensä lisukkeita käyttävässä luokassa on omiakin ominaisuuksia.
class MotifTextWindow implements Window extends StdWindowShell, MotifWindowBorders, TextWindowContents { }