Springen naar inhoud

Interface in oo


  • Log in om te kunnen reageren

#1

zpidermen

    zpidermen


  • >1k berichten
  • 1623 berichten
  • Ervaren gebruiker

Geplaatst op 23 september 2008 - 17:02

Kan iemand mij in simpele termen uitleggen wat een interface nu eigenlijk is (in termen van object orientatie), hoe je een interface kan/moet gebruiken, en vooral waarom je een interface zou gebruiken (in welke situaties). Ik kom de term best wel met enige regelmaat tegen, maar om de een of andere reden snap ik het nog steeds niet. Ik weet dat het iets te maken heeft met abstracte klassen, maar dan houdt het voor mij ook wel zo'n beetje op.
Beter kaal als geen haar want een kip snurkt

Dit forum kan gratis blijven vanwege banners als deze. Door te registeren zal de onderstaande banner overigens verdwijnen.

#2

Raga

    Raga


  • >25 berichten
  • 99 berichten
  • Lorentziaan

Geplaatst op 23 september 2008 - 17:57

hoi, hier valt een hoop over te zeggen :D
daarom zal ik eerst maar wat korte antwoorden geven, dan moet je daarna maar doorvragen over wat nog onduidelijk is.

wat is een interface?
Een interface is in feite een contractspecificatie.
Een interface implementeert niets, maar geeft aan hoe de interactie met de buitenwereld werkt.
een simpel voorbeeld in pseudocode:
interface ISystem
{
start()
stop()
}

als je met een ISystem te maken hebt, weet je nu dat je dat ding kunt starten en stoppen.

hoe gebruik je een interface?
Meestal zul je een interface definieren zoals ik boven gedaan hebt.
Vervolgens zul je klasses gaan definieren die de interface implementeren.
In dit geval zullen ze een startfunctie en een stopfunctie moeten implementeren.

voordeel van interfaces?
Stel je hebt een aantal systemen, als voorbeeld een computer, printer, en een monitor.
Als deze systemen nu zijn afgeleid van ISystem, dan kun je ze allemaal behandelen als een ISystem,
zodat je altijd start en stop kunt aanroepen.
Kort gezegd, gebruik je interfaces bij klasses die op dezelfde manier met de buitenwereld communiceren (start/stop);
hoe zij dat starten en stoppen precies doen, kan wel helemaal verschillend zijn.
Raga

#3

Cycloon

    Cycloon


  • >1k berichten
  • 4810 berichten
  • VIP

Geplaatst op 23 september 2008 - 19:15

Een interface is inderdaad een blauwdruk van hoe een klasse die het implementeert er minstens moet uitzien. Die interface kan bv Auto zijn. Elke auto moet sowieso een rem en gaspedaal hebben. In je interface kan je dus zetten dat er een functie rempedaal en een functie gaspedaal moet zijn. Een interface zegt echter niks over hoe dit precies moet gebeuren.

Nu kan je dus allemaal klassen gaan maken die de interface Auto implementeren. Zo kan je bv een ford, bmw, saab, peugeot maken die allemaal auto's zullen zijn en dus zeker een rem- en gaspedaal zullen hebben als ze de interface implementeren.

Als we dan specifiek naar Java kijken dan heeft het nog een voordeel. In java kan je niet afleiden van 2 klassen, het is dus niet mogelijk om bv een ford af te leiden van een 'voertuig' en een 'auto' klasse. Als je een voertuig en auto interface maakt dan kan je wel beiden implenteren.

Een interface gebruik je vooral wanneer je veel gaat gebruik maken van polyformisme zonder dat je een bovenklasse kan maken die op zichzelf staat.

#4

zpidermen

    zpidermen


  • >1k berichten
  • 1623 berichten
  • Ervaren gebruiker

Geplaatst op 23 september 2008 - 20:51

Ja maar je kunt toch ook een superklasse 'auto' maken, met subklassen 'bmw', 'ford', enz die allemaal de methodes en eigenschappen van de superklasse overerven? Wat is dan het verschil tussen een superklasse (ik weet niet helemaal zeker of dit wel een correcte term is) en een interface? En wanneer kun je dan beter gebruik maken van een interface dan van een superklasse?

Ohnee wacht even... een subklasse 'bmw' is eigenlijk een object, een instantie van de klasse 'auto'. Een subklasse zou in dit voorbeeld bijv. 'electrische auto', 'benzineauto', ... kunnen zijn.

Nee, ik snap op zich nu wel dat een klasse dus methodes van een interface kan 'overerven' hoewel de term niet helemaal correct is, aangezien de methode op heel verschillende manieren geimplementeerd kan worden. Wat is dan het nut van het 'overerven' van methodes van een interface, als je vervolgens nog die methode helemaal moet implementeren? Of om het voorbeeld van Raga te nemen: je weet dan wel dat een klasse die de interface implementeert een 'start' en een 'stop' methode bevat, maar je weet nog niet hoe het starten en stoppen in z'n werk gaat. Want dat zal je in de klasse zelf nog moeten implementeren.

Veranderd door zpidermen, 23 september 2008 - 20:56

Beter kaal als geen haar want een kip snurkt

#5

Raga

    Raga


  • >25 berichten
  • 99 berichten
  • Lorentziaan

Geplaatst op 23 september 2008 - 21:44

Het verschil tussen interface en superklasse is dat een interface geen implementatie bevat (een superklasse vaak wel), en in de meeste talen kun je een klasse slechts van maximaal 1 klasse overerven, maar je kunt van meerdere interface afleiden.

nog even over dat starten en stoppen:
Je weet inderdaad niet HOE ze precies starten en stoppen.
Maar het idee is dat je dat ook niet wilt/mag weten;
dat is namelijk een zaak van die klasse zelf, en die implementatie scherm je dus af.
Het idee is dat jij zegt starten tegen een object en dat object bepaalt zelf wel hoe.
Raga

#6

Cycloon

    Cycloon


  • >1k berichten
  • 4810 berichten
  • VIP

Geplaatst op 24 september 2008 - 13:18

Een interface is iets dat het vooral makkelijk moet maken om in groepsverband te kunnen werken. Je kan op voorhand de interface in orde brengen en zeggen dat iedereen verplicht de interface moet implementeren.

Anderzijds is het belangrijk zoals ik reeds zei omdat bv Java geen meervoudige overerving kent (itt c++). De enige optie is dan interfaces gebruiken.

In principe kan je bv ook perfect met een abstracte bovenklasse werken, dan doet het eigenlijk ongeveer wat een interface doet.

Het is moeilijk om dit eigenlijk zomaar uit te leggen, je moet dit echt kunnen zien in bepaalde code waaruit duidelijk naar voor komt dat een interface op momenten heel handig kan zijn.

#7

zpidermen

    zpidermen


  • >1k berichten
  • 1623 berichten
  • Ervaren gebruiker

Geplaatst op 25 september 2008 - 16:48

Je weet inderdaad niet HOE ze precies starten en stoppen.
Maar het idee is dat je dat ook niet wilt/mag weten;

Waarom niet? Stel dat je wel weet hoe er gestart en gestopt wordt, dan is dat toch geen probleem?

Het is moeilijk om dit eigenlijk zomaar uit te leggen, je moet dit echt kunnen zien in bepaalde code waaruit duidelijk naar voor komt dat een interface op momenten heel handig kan zijn.

Heb je misschien een stukje code waarin naar voren komt dat een interface in die betreffende situatie handiger is dan een superklasse?

Zoals ik het nu zie, krijg ik de indruk dat je beter maar helemaal geen gebruik meer moet maken van een superklasse, maar beter om voortaan van een interface gebruik te maken. Hoewel, stel dat een methode 'Start()' voor alle subklasses op dezelfde manier geimplementeerd wordt, dan is een superklasse weer handig, want om nou hetzelfde stukje code (nl. die van de methode 'Start()') bij alle subklasses te plaatsen is ook een beetje overdreven. Maar in alle andere gevallen kun je dus beter gebruik maken van interfaces?
Beter kaal als geen haar want een kip snurkt

#8

Cycloon

    Cycloon


  • >1k berichten
  • 4810 berichten
  • VIP

Geplaatst op 25 september 2008 - 17:56

Heb je misschien een stukje code waarin naar voren komt dat een interface in die betreffende situatie handiger is dan een superklasse?


Een stukje code heb ik niet echt. Interfaces worden meestal enkel gebruikt in de iets grotere projecten en ik denk niet dat je daardoor direct een stuk wijzer wordt.

Zoals ik het nu zie, krijg ik de indruk dat je beter maar helemaal geen gebruik meer moet maken van een superklasse, maar beter om voortaan van een interface gebruik te maken. Hoewel, stel dat een methode 'Start()' voor alle subklasses op dezelfde manier geimplementeerd wordt, dan is een superklasse weer handig, want om nou hetzelfde stukje code (nl. die van de methode 'Start()') bij alle subklasses te plaatsen is ook een beetje overdreven. Maar in alle andere gevallen kun je dus beter gebruik maken van interfaces?


Een superklasse is enkel handig zoals je zelf aanhaalt wanneer je bepaalde functies kan implementeren die alle afgeleide klassen zeker ook zullen hebben en die altijd op dezelfde manier geprogrammeerd zal zijn. Echter komt dit niet zo heel vaak voor. Vaak kom je te zitten met klassen die allemaal wel op mekaar gelijken, maar niet op dezelfde manier werken. Op dat moment kan je geen superklasse meer maken die op zichzelf kan bestaan.

Misschien toch nog een voorbeeld waar een superklasse niet meer zinnig is:

Klasse voertuig:
Een voertuig heeft altijd een plaats voor een persoon te vervoeren.
Het moet kunnen stoppen en starten.
Het heeft een bepaalde aandrijvingskracht nodig.

Natuurlijk is een voertuig niet iets dat op zichzelf kan bestaan. Als ik jou nu vraag om een voertuig te maken in het echte leven zal jij misschien een fiets maken en een ander persoon een go-cart en nog een ander persoon een auto. Het voertuig zelf is niet iets dat op zichzelf kan bestaan, het moet altijd verder gespecifieerd worden. Echter weet iedereen perfect dat een voertuig bepaalde eisen heeft zoals die hierboven staat. Je zou nu kunnen stellen dat voertuig een interface is.

Interface voertuig {
	 void Start();
	 void Stop();
	 boolean persoonAanwezig();
}

Je kan nu gaan zeggen dat zowel een go-cart als een fiets berusten op hetzelfde principe qua aandrijving. Beide hebben tandwielen nodig en een ketting waaraan pedalen vasthangen. Beiden zullen dus dezelfde soort Start() methode kennen. Je kan dus een superklasse maken tandwielAangedreven.

Class tandwielAangedreven implements voertuig {
	 void Start() {
		  // ga op de trappers staan en draai ze rond
	 }
}

Stel nu dat je van voertuig een bovenklasse had gemaakt dan hadden we nu een probleem met de auto. Een auto is ook een voertuig, maar kent een heel andere startmethode. Nu kon je wel de auto een aparte start methode meegeven maar elke keer je de auto zou willen starten dan zou je het object als 'Auto' en niet als 'Voertuig' moeten aanspreken. Wanneer je bv een tabel van voertuigen hebt zou je elke keer moeten checken of je een auto hebt of iets anders en als je een auto had zou je deze elke keer moeten casten. Je ziet dus dat je al in de knoop begint te geraken omdat een auto op een totaal andere manier de startfunctie moet programmeren.

Nu we de interface hebben gemaakt kunnen we perfect een tabel van voertuigen aanmaken en van alle elementen de start() methode oproepen zonder ons zorgen te hoeven maken of een bepaalde object een eigen specifieke start methode heeft.

Ik hoop dat het nu duidelijk is wanneer je een interface gebruikt en wanneer een bovenklasse.

Hier nog een kort schema van de mogelijke indeling:

Voertuig (interface)
												/			   \
						 tandwielAangedreven (klasse)	Auto (klasse)
							/					  \
					  Fiets (klasse)	 Go-cart (klasse)

Veranderd door Cycloon, 25 september 2008 - 17:57


#9

Pr.Prlwytskovsky

    Pr.Prlwytskovsky


  • >25 berichten
  • 38 berichten
  • Gebruiker

Geplaatst op 25 september 2008 - 18:13

Uh, in mijn hoofd is een interface een kunstgreep om multiple inheritance mogelijk te maken bij talen die dat niet ondersteunen. Ik ben niet zo goed in de oo-terminologie dus meteen maar concreet:

Stel in jouw project heb je de klassen voertuig->auto->benzine_auto en het bekende dier->zoogdier->koe. Daarnaast heb je een slachthuis waar je een koe kan laten slachten ( slachthuis.slacht( Koe koe); )

Nu komt het moment dat je een benzineauto_koe nodig hebt, iets dat kan starten, stoppen, loeien, melk geven etc. Je kunt geen multiple-inheritance gebruiken dus kies je ervoor om een nieuwe klasse te maken die een benzineauto is, en een koe heeft. De methodes Loei, GeefMelk etc zal je dan opnieuw moeten schrijven, en laten doorsluizen naar je koe. Beetje vervelend werk, maar goed, je benzineauto_koe ziet eruit als een koe...

alleen... je kan hem niet naar het slachthuis brengen, want die verwacht een echte koe!

Oplossing is dan een interface. Terug naar je koe en de methodes Loei etc groeperen in een interface, terug naar je slachthuis en die geen koe maar een koeieninterface laten accepteren, en terug naar je benzineauto_koe om die geen koe te laten hebben maar een koeieninterface.

Rotwerk.. niks fraais.. kunstgreep. Maar mischien begrijp ik het verkeerd, mijn oo-kennis is nogal van de kouwe-grond.

#10

Bart

    Bart


  • >5k berichten
  • 7224 berichten
  • VIP

Geplaatst op 25 september 2008 - 18:58

Uh, in mijn hoofd is een interface een kunstgreep om multiple inheritance mogelijk te maken bij talen die dat niet ondersteunen. Ik ben niet zo goed in de oo-terminologie dus meteen maar concreet:


Niet correct. Interfaces zijn veel meer dan alleen een kunstgreep. Ze zijn namelijk erg belangrijk als twee objecten met elkaar willen communceren en data doorgeven. In dat geval moet er vastgelegt worden hoe dit gebeurt, en daar komen interfaces om de hoek kijken.

Multiple inheritance is iets anders dan het gebruik van interfaces.

Overigens is het zo dat als je multiple inheritance nodig hebt in je programma, je nog eens goed naar je software architectuur moet gaan kijken.
If I have seen further it is by standing on the shoulders of giants.-- Isaac Newton





0 gebruiker(s) lezen dit onderwerp

0 leden, 0 bezoekers, 0 anonieme gebruikers

Ook adverteren op onze website? Lees hier meer!

Gesponsorde vacatures

Vacatures