Vraag & Antwoord

Webprogrammeren & scripting

[PHP] OOP beginner met vragen

12 antwoorden
  • Ik heb enkele dagen geleden een beginnetje gemaakt met OOP in PHP, met behulp van [url=http://www.killerphp.com/tutorials/object-oriented-php/]deze tutorial[/url] Op zich valt het tot nu toe redelijk mee. Waarschuwingen vooraf dat het taai en misschien onlogisch en ongebrijpelijk over zal komen zijn (nog) niet op mij van toepassing. Tot nu toe vind ik het erg logisch in elkaar zitten en zelfs een oplossing voor mijn manier van werken (waarbij ik allerlei losse scriptjes met allemaal een eigen functie lustig include ;-)) Op dit moment zit ik met twee vragen: In de method van een class gebruik je vaak een soort van variabele/handle. Voorbeeldje: [code:1:96e5d92a0b] $this->dingetje = $inputstring; [/code:1:96e5d92a0b] Dat 'dingetje', wat is het en hoe heet het? Het lijkt als een soort interne variabele van de method te functioneren. Verder kom ik een hele sectie tegen hoe je 'parent methods' kunt overriden als je een nieuwe class aanmaakt als extend van een parent class. Als ik dat zo lees dan denk ik: Waarom zou ik een bestaande method een nieuwe functie willen geven? Dat werkt toch alleen maar verwarring in de hand? Dan kan ik toch veel beter dat hele overriden achterwege laten en gewoon een nieuwe method aanmaken? De hele gedachte achter OOP is toch dat het overzichtelijker en begrijpelijker moet zijn? maar met anderhalve dag OOP ervaring is mijn mening nu ook weer niet bepaald de meest solide natuurlijk, dus misschien sla ik hier de plank mis?
  • Je hebt blijkbaar een eigen class gemaakt met daarin "dingetje". Van deze class heb je een instantie gemaakt en deze heb je in de variabele $this gestopt. Het "dingetje" wordt vaak een variabele of attribute genoemd. Een attribute en dus eigenlijk een gegeven die binnen die class beschikbaar is. (hopelijk is dit een beetje duidelijk) Met overriding zijn een aantal dingen mogelijk. Ik zal je twee voorbeelden geven. Stel je hebt een (web-)applicatie waarin je module's maakt, zoals een gastenboek, een foto-album en een contact-formulier. De pagina die deze module laadt weet natuurlijk dat er een module is, maar niet per se welke. Je zou dit op kunnen lossen door een module class te maken waarin je de functies (ofwel methodes) zet die relevant zijn voor de hoofdpagina. De drie modules extenden deze module class. Op deze manier kan de hoofdpagina tegen de module praten, zonder precies te weten hoe of wat er aan de hand is. Eigenlijk voeg je dus een zekere abstractie toe aan je pagina (wat in principe goed is). Een andere voorbeeldje.. Stel je hebt een auto. Deze heeftde attributen brandstof, maxSnelheid en kleur (en nog een boel andere dingen.. maar dit is genoeg voor het voorbeeld). Nou heb je nog een auto die eigenlijk hetzelfde is, maar alleen de maxSnelheid is anders. Je kunt dus makkelijk deze nieuwe auto aanmaken door je oude auto over te erven en de maxSnelheid aan te passen. Dit zijn slechts twee voorbeelden van overerving.. ik kan nog wel meer bedenken maar ik denk dat het nou duidelijk zou moeten zijn :) Succes ;)
  • Het is heel erg duidelijk, hartstikke bedankt!
  • Allereerst: de volgende online tutorial legt alles (naar mijn ervaring) in kleine begrijpelijke stappen uit, terwijl het toch uiteindelijk diep op de stof ingaat: [url=http://hudzilla.org/phpwiki/index.php?title=Main_Page]Practical PHP Programming[/url]. Dan een aanvulling op yendis: Het idee is bij OOP dat je de interactie in je applicatie gaat benaderen als objecten. Hoewel het in het begin makkelijk lijkt zal je een bepaalde handigheid moeten krijgen in het kiezen van deze objecten. Deze keuze bepaalt namelijk in belangrijke mate het voordeel van OOP boven functioneel programmeren. Het is namelijk niet gezegd dat iemand die heel bedreven is in de kunst van het functioneel programmeren slechtere code schrijft dan iemand die OOP programmeert. Het voornaamste verschil zit 'm in de zgn [i:69d851854e]scope[/i:69d851854e] van variabelen en methoden. Ik zal deze vage introductie hier stoppen, aangezien het iets is dat je voornamelijk zal moeten ervaren. Dan het antwoord op je vragen. In jouw voorbeeld noem je $this. Je voorbeeld is hier zeer ongunstig gekozen, $this is namelijk een term die is voorgedefinieerd en zelf variabelen aanmaken die deze naam gebruiken is op z'n zachtst gezegd niet handig en kan leiden tot onvoorspelbaar gedrag van je code. Laten we voor dit voorbeeld een variabele $foo nemen, een in de programmeerwereld bekende "willekeurige naam" voor een variabele. Als uitgangspunt is er de klasse. Deze definieert het object, met andere woorden: je geeft aan welke variabelen het object heeft, welke methoden het object kent, en of deze [i:69d851854e]public[/i:69d851854e], [i:69d851854e]private[/i:69d851854e] of [i:69d851854e]protected[/i:69d851854e] zijn. Dit zijn als het ware de afspraken die je met het systeem maakt. Eenmaal gedefinieerd kan je een object initialiseren, wat ze ook wel beschrijven als een instantie maken van een klasse. Feitelijk betekent het dat je een variabele hebt (in dit geval $foo) die voldoet aan de afspraken die je ervoor het opgesteld (hebt gedefinieerd in je klasse). Als je dat gedaan hebt dan kan je alleen (!) de publieke methoden en variabelen aanspreken. Het aanroepen van methoden of variabelen die niet bestaan of niet publiek zijn zal dan ook onherroepelijk leiden tot foutmeldingen. Ook dit alles is een redelijk vage en abstracte beschrijving, maar ook hier geldt dat ervaring een hoop zal verduidelijken. Hoe dan ook, $dingetje is in jouw voorbeeld een publieke variabele van het object in instantie $foo (of in jouw geval $this). $this is de manier waarop je binnen de klasse wil aangeven dat je variabelen/methoden van binnen de klasse wil gebruiken, met name omdat je misschien ook wel variabelen/methoden hebt buiten de instantie met dezelfde naam. Dan het overschrijven van methoden. Dit is meestal iets dat je doet als je gebruik maakt van zgn [i:69d851854e]interfaces[/i:69d851854e] of - iets heel anders - overerving. Het eerste is een verhaal apart, het laatstgenoemde komt in het begin vaker voor. Overerving komt meestal voor als je een algemene klasse (laten we "hond" als voorbeeld nemen) gaat specialiseren in specieke klassen (zoals "bouvier" en "chowchow"). [b:69d851854e]hond[/b:69d851854e] kan een methode hebben genaamd "blaffen()" die de tekst "waf waf" naar het scherm schrijft. Voor een hond in het algemeen voldoende, maar voor een bouvier wil je graag "woef" hebben en voor een chow chow liever "kef". Dit kan je al in de klasse vastleggen en dan noem je dat het herdefinieren van de methode in een klasse. Ik hoop dat het ondanks de lengte van stof en de abstractheid ervan het allemaal nog duidelijker is geworden. Het is toch boven alles een complex paradigma dat aangeleerd moet worden. Zo niet, vrees niet om het te vragen, ik zal mijn best doen zo concreet mogelijk te antwoorden. - Bas
  • Tnx voor dit uitgebreide antwoord. Even gauw over $this, ik had in de tutorial al begrepen dat het een variable is dat voorgedefinieerd is en zo had ik het in het voorbeeld ook al bedoeld. Ik heb het in het voorbeeld gezet om zo drie verschillende soorten van variabelen achter elkaar te hebben zodat ik het onderscheid goed kan aangeven. Verder had ik veel van wat je uitlegt al begrepen uit de tutorial (classes zijn een soort van blueprints voor de instances die je daarna pas gaat creeren, extends zijn 'childs' van 'parent' classes, public, private en protected properties en methods (al weet ik nu nog niet waar ik dat voor zou willen gebruiken) e.d.) Dessalniettemin is het fijn om het in een andere formulering nogmaals uitgelegd te krijgen omdat ik het op die manier nog gemakkelijker oppak. Ik ben ook erg blij met de tutorial die je meegeeft, want zo kan ik weer verder. Verder zal ik inderdaad eerst wat beter in OOP thuis moeten raken voordat ik er echt mee uit de voeten kan, met name om wat je aangeeft, niet alleen de 'technische' kennis is belangrijk, ook het toepassingsgebied kennen. Iets wat binnen scripting sowieso al van toepassing is: dingen kunnen meestal op 10 verschillende manieren bereikt worden. De kunst is echter om de methode te kiezen die het beste is. (En soms is dat zelfs om helemaal af te zien van server side scripting, vandaar dat ik van de week ook maar eens in de javaScript gedoken ben) Vragen zullen er zeker nog komen. Momenteel heb ik er al een nadat ik variabelen in een object/instance wilde gebruiken die ik in een config bestandje had staan die in de "hoofd" php bestand geinclude waren. (M.a.w. in b.v. "main.php" heb ik include ("config.php"); en vervolgens roep ik de instance aan die variabelen uit het config bestandje moet gebruiken) dat lukt me niet zonder de hele rits variabelen naar een array te kopieren en die array vervolgens mee te geven in het aanroepen van de instance. ($handle->print_data(""); werkt uiteraard niet, dus het moest $handle->print_data($array); worden)
  • [quote:c6e6b88d33="Gooly"]Vragen zullen er zeker nog komen. Momenteel heb ik er al een nadat ik variabelen in een object/instance wilde gebruiken die ik in een config bestandje had staan die in de "hoofd" php bestand geinclude waren. (M.a.w. in b.v. "main.php" heb ik include ("config.php"); en vervolgens roep ik de instance aan die variabelen uit het config bestandje moet gebruiken) dat lukt me niet zonder de hele rits variabelen naar een array te kopieren en die array vervolgens mee te geven in het aanroepen van de instance. ($handle->print_data(""); werkt uiteraard niet, dus het moest $handle->print_data($array); worden)[/quote:c6e6b88d33]Als de instantie afhankelijk is van de waarden uit config.php dan is het waarschijnlijk handiger om die waarden mee te geven bij het initialiseren van het object, ofwel: geef het gelijk mee via de constructor van de klasse. Zorg er dan natuurlijk wel voor dat je alleen een constructor hebt mét parameters, anders maak je het jezelf moeilijker dan nodig is. - Bas
  • Inmiddels zijn de constructors hier ook duidelijk. Dat is inderdaad een goeie optie. Momenteel ben ik bezig met iets wat ik waarschijnlijk alleen maar uit de praktijk kan leren: Classes of functies. Wanneer een class en wanneer een functie. Vooralsnog houd ik de vuistregel aan: wil ik dezelfde functionaliteit in meerdere scripts kunnen gebruiken en ik wil in staat zijn om de functionaliteit achteraf gamakkelijk aan te kunnen passen, dan wordt het een class. Anders wordt het een functie.
  • Het gebruik van klassen en functies is iets dat na een tijdje vrijwel automatisch goed gaat. Om het programmeren gevoelsmatig goed te laten gaan kan je ervan uitgaan dat klassen altijd iets uit het echte leven representeren. Denk hier aan concrete dingen als bijv een auto, maar ook abstracte dingen als een vereniging. Methoden binnen deze klasse hebben dan altijd betrekking op het object zelf, je kan ze iets vragen of iets vertellen. Een functie is nog een stap abstracter dan dit. Stel dat je bijvoorbeeld een functie maakt om de grootste gemene deler te berekenen uit twee integers, dan stop je dat niet in een klasse. (Kan overigens natuurlijk wel, maar zelf vind ik niet dat algemene berekeningen daar thuis horen.) Uiteraard blijft er altijd een grijs gebied die genoeg stof geeft tot discussie, dat is echt iets waar je zelf een fijne aanpak moet gaan vinden. Succes! :D - Bas
  • ik ben zelf tegenwoordig geheel overgegaan op OO, dus ook integer-functies. Je kan die in een klasse stoppen en allemaal static maken; bijv Functions of Tools. Vgl met java.utils.Math ofzo. Wanneer je je klasse namen met een directory stryuctuur over een laat komen, kan je mbv van de autoload (helaas als enige dus niet in een klasse) functie altijd gemakkelijk de klassen laten laden. Je code vblijft dan overzichtelijk omdat je gemakkelijk kunt zien welke functies van PHP zelf zijn (zonder klassenaam) en welke van jezelf. En van die laatste kun je ook zien in welk bestand je moet kijken voor de definitie.
  • Tnx Marientje, maar eh... you lost me there completely ;-)
  • Ik ging in op de reactie van BasHamar. Gewone integerfuncties zet ik ook in een klasse, bijvoorbeeld genaamd Functions of Tools: [code:1:e260c7a1d1]class Tools { public static function gcd(a, b) { return c; } // to be completed } [/code:1:e260c7a1d1] Aanroepen kan nu met Tools:gcd(a, b) ipv het normale gcd(a, b) wanneer je de functie buiten een klasse had aangeroepen. Dit lijkt omslachtig omdat je nu ook de klassenaam moet noemen. Voordeel, vind ik, is dat je gelijk ziet waar de functie is gedefinieerd. Dat is al helemaal wanneer er een sterke relatie is tussen klasse-namen en bestandsnamen. Wanneer je elke klasse in een apart bestand definieert met gelijknamige naam (...), kun je dus ook heel makkelijk de definitie vinden van Tools.gcd. Wanneer je dit hebt gedaan, kijk dan eens naar [url=http://nl.php.net/autoload]autoload[/url]. Deze functie wordt aangeroepen wanneer een klasse nog niet bestaat, je kan dynamisch proberen het juiste bestand alsnog in te laden. Je hoeft dan dus niet meer op elke pagina include('Tools.php') te zetten maar kan aan de autoload functie overlaten dat dat bestand wordt ingeladen. Dat gaat heel makkelijk wanneer er een directe koppeling is tussen een klasse- en bestandsnaam. In de documentatie staat gelijk een voorbeeld hoe je het zou kunnen doen. Misschien veiliger is om al je classes in een subdirectory te gooien. Ikh oop dat je het zo begrijpt en dat ik misschien wel meer mensen heb overtuigd van dit, in mijn ogen, o zo mooie.
  • Ik ben overtuigd. ;) Ik moet toegeven dat het groeperen van eigen functies en de daarbij horende voordelen nog niet helemaal waren doorgedrongen. Overigens gebruik ik wel autoload(), dus dit moet mooi in te passen zijn in mijn komende hobbyproject. Persoonlijk plaats ik klassen altijd in directories en laat ik de bestandsnamen eindigen op ".class.php", dat lijkt me én veilig én is overzichtelijk in een willekeurig bestandsbeheerprogramma. Ik kan het waarderen dat je doorging op de grootste gemene deler. :D - Bas

Beantwoord deze vraag

Weet jij het antwoord op deze vraag? Registreer of meld je aan met je account

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.