Ståle Skrevet 20. mars 2008 Del Skrevet 20. mars 2008 Jeg prover meg litt med klasser. I index.php deklarerer jeg $log $log = new log_event(); sa trenger jeg a logge events i en av de andre klassene. function __construct{) { global $log } men hvordan far jeg tak i funksjonene til $log fra en funksjon i den andre klassen? Lenke til kommentar
dabear Skrevet 20. mars 2008 Del Skrevet 20. mars 2008 (endret) For det første er det vanlig å begynne en klasse med stor bokstav, underscoreblir brukt bare for å separere pakkenavn fra klassenavn. For det andre ansees "global" for å være en dirty måte å gjøre det på. Gi det heller til konstruktøren. Her er mitt forslag: class MyClass { //$log må være instans av LogEvent-klassen public function __construct(LogEvent $log) { $this->log = $log; } } Da må du initialisere klassen med $my_new_object = new MyClass($log); Videre bruker du $this->log i metodene dine for å referere til loggobjektet. Endret 20. mars 2008 av dabear Lenke til kommentar
Ståle Skrevet 20. mars 2008 Del Skrevet 20. mars 2008 greitt, men ville ha tak i funksjonen $log->log(); i fra en annen klasse. Og ved a da initialisere klassen med klassen som et argument, far jeg ikke tak i log(). $this->log->log(); pa en mate. Lenke til kommentar
dabear Skrevet 20. mars 2008 Del Skrevet 20. mars 2008 Vel Ståle, du gav deg sjøl svaret. Dersom du initialiserte $this->log variabelen i konstruktøren, skal dette funke: $this->log->log(); pa en mate. Lenke til kommentar
Ståle Skrevet 20. mars 2008 Del Skrevet 20. mars 2008 Se der ja Det var nok noe annet som var feil da jeg provde det med global. Men na virka det ja. Lenke til kommentar
Anonym5656 Skrevet 21. mars 2008 Del Skrevet 21. mars 2008 Noen som sitter på noen gode guider/tutorials om hvordan man kan bruke OOP(class, extends, interface, method osv) i et "real-life" prosjekt? Altså at de ikke bare forklarer hva som er hva og hva det heter, men bruker et eksempel/eksempler som er realistisk(ikke noe foobar med andre ord). Lenke til kommentar
Garanti Skrevet 21. mars 2008 Del Skrevet 21. mars 2008 Henger meg på Gakkakk, noen som har guider? Lenke til kommentar
MC2 Skrevet 22. mars 2008 Del Skrevet 22. mars 2008 Kan vel prøve å gi deg en kort forklaring. Hele poenget med OOP er å representere verden i din kode, og med det så tenker man at diverse ting kan bli delt opp i klasser. Feks. så er mennesker en klasse. Dyr en annen. Et menneske er da et objekt av klassen mennesker (det samme med en dyr). En klasse beskriver hvordan objekter av den klassen er, altså med egenskaper og funksjonalitet (properties, methods). Navnet på en klasse er som oftest et substantiv. <?php class Human { public $name; } // lag et menneske (altså, et objekt av klassen human) $etMenneske = new Human(); // $etMenneske er nå en peker til et Human objekt // feks. for å sette navnet på mennesket $etMenneske->name = "Homer"; ?> Det med subklasser, altså extends er sånn at hvis alt blir delt opp i klasser, så kan alt deles opp i sub-klasser. Altså alt er i et hieraki. Feks, så er Mann en sub-klasse av menneske. En dog en sub-klasse av animal, og hvis vi vil gå videre, en bulldog en subklasse av dog (som allerede er en subklasse av animal). Det siste eksemplet hadde sett sånn ut: <?php class Animal { public $says = "hello"; } class Dog extends Animal { public $says = "bark"; public function bark() { echo "woof!"; } } class Bulldog extends Dog { public $food = "beer"; public function bark() { echo "I am a bulldog!"; } } ?> <?php $dyr = new Animal(); echo $dyr->says; // skriver "hello" $hund = new Dog(); echo $hund->says; // skriver "bark" $hund->bark(); // skriver "woof" $bulldog = new Bulldog(); echo $bulldog->says; // skriver "bark" echo $bulldog->food; // skriver "beer" $bulldog->bark(); // skriver "I am a bulldog" Når man definerer enda en variabel i en subklasse (som "says"-variablen i Dog klassen) så "overrider" den Animal sin "says" variabel. Dette kan du gjøre med metoder også (altså function definisjoner). Når det gjelder interfaces så må man først kjenne til abstrakte klasser. En abstrakt klasse er en klasse som man ikke kan lage et objekt av. Feks. så kunne Animal klassen ha vært abstrakt (da hadde deklarasjonen vært abstract class Animal { ... ). Da kan man ikke lage objekter av den klassen ($dyr = new Animal() går ikke). Men andre klasser skal da utvide den med extend. Grunnen for dette er at et dyr er da ikke bare et dyr, men er da en spesifik type dyr. Et annet eksempel er feks. å ha en abstrakt klasse Menneske, som da har to subklasser Kvinne og Mann. Et menneske kan ikke bare være et menneske, et menneske må være enten Mann eller Kvinne, som da er subklasser av Menneske. Hvis du har et objekt av Bulldog så er det en child av Dog, og Dog er en parent av Bulldog. Hvis du la merke til "bark" metoden i Bulldog og "bark" metoden i Dog så la du sikkert merke til at de var deklarert på samme måte. Det vil si at "bark" metoden i Bulldog polymorfer "bark" metoden i Dog, altså den i Bulldog blir brukt når du lager et objekt av Bulldog, mens den "bark" metoden i Dog blir brukt når du lager et objekt av Dog klassen. Et interface er en veldig abstrakt klasse som ikke burde følge hierakien. Klasser som implementerer et interface har en eller annen egenskap felles. Feks. så hadde både en Banana, Star og Giraffe implementert klassen Yellow siden de begge er gule, men de er jo ikke en felles parent. Et interface kan ikke ha noe innhold. Feks. et Yellow interface kanskje må ha en metode som sier hvilken farge det er (dårlig eksempel). Et typisk interface ser sånn ut: <?php interface Yellow { public function color(); // alle klasser som implementer dette interfacet må polymorfe denne metoden (altså deklarer denne metoden) og den må være public (mer om det senere) } interface Spots { // trenger ikke å ha noe i det hele tatt (det trenger ikke vanlige klasser heller) } ?> Og Banan og Giraffe hadde vært deklaret sånn: <?php class Banana implements Yellow { public function color() { echo "A banana is yellow!"; } } // feks. class Giraffe extends Animal implements Yellow, Spots { public function color() { echo "A giraffe is yellow with brown spots!"; } } // dette går ikke class Star implements Yellow { // ingen deklarasjon av color metoden } Nevnte også ordet public. Når du deklarer enten en variabel eller en metode som public så betyr det at alle har tilgang til det. Eks: <?php // extend og implement er unødvendig i dette eksemplet, men er der for å illustrere hieraki og tankemåte class Cow extends Animal implements Spots { public $name = "dolly"; public function milk() { echo $this->name." is being milked!"; // $this er en peker til seg selv, ellers får du ikke tak på $name } public function sleep() { echo $this->milk()." and is now tired!"; } } $ku = new Cow(); echo $ku->name; // 1 $ku->milk(); // 2 $ku->sleep(); // 3 Når alt er deklarert som public så fungerer både 1 2 og 3. Men dersom $name er deklarert som private så fungerer ikke nr. 1. En private deklarasjon betyr at bare et objekt av den klassen har lov å bruke den. Dersom milk() også hadde vært private så hadde ikke nr. 2 fungert, men nr. 3 fungerer forsatt. Men om du lager subklasser av Cow, feks en subklasse kalt Bambi (dårlig eksempel) så har ikke en metode i Bambi klassen tilgang til en metode eller variabel deklarert som private i Cow klassen. Private betyr privat for bare objekter av den klassen. Men dersom både $name og milk hadde vært deklarert som protected istedet så hadde metoder i Bambi tilgang til milk og $name. Man har også et nøkkelord som heter final. Og man bruker det sånn: <?php class Human { public final function help() { echo "F1! F1!"; } } class Man extends Human { // ikke lov å polymorfe denne metoden siden den er deklarert som final i parent klassen Human. public function help() { } } Grunnen man har public, private, protected og final er for at man skal ha bedre kontroll over sikkerhet. Feks. i en database klasse er det ikke så gunstig å la passord være public for da kan andre objekter få tak på det, og endre det. Håper det var litt klarere. Lenke til kommentar
Anonym5656 Skrevet 22. mars 2008 Del Skrevet 22. mars 2008 Fin og kjapp innføring det MC2. Vet ikke helt hva Garanti var ute etter, men poenget mitt var at det skulle være et realistisk eksempel(f.eks. en blogg, huskeliste, handlekurv o.l.), og hvordan man skal bruke OOP i den sammenhengen. Mulig jeg er litt dårlig til å forklare akkurat det her Lenke til kommentar
Ernie Skrevet 22. mars 2008 Del Skrevet 22. mars 2008 (endret) Tja, hvis du er ute etter litt «real world» eksempler på kan jo kanskje dette være noe: Extend/arv Extend er nyttig når du vil utvide funksjonaliteten i en klasse, men samtidig vil beholde den gamle. Et eksempel kan være at du bruker et rammeverk og ergrer deg over at f.eks user-klassen ikke støtter tilgangsrettigheter på den måten du ønsker. I stedet for å endre klassen fysisk (som vil gjøre det vanskelig å oppdatere seinere) kan du arve fra user-klassen og legge til det du trenger. I f.eks java brukes arv ekstremt mye til å arve fra komponenter osv. for å kunne utvide funksjonaliteten. I stedet for å lage en ny klasse som er «main»-klassen i applikasjonen med et JFrame-objekt inni arver man i stedet fra JFrame (hovedvinduet). Et annet eksempel (igjen fra java) er at man av og til trenger å overstyre toString-metoden (i f.eks JLabel) for å få ut noe vettugt i stedet for javax.swing.osv. Interface Interface gir ikke umiddelbart mye mening i PHP, men definerer et sett funksjoner klassene som implementerer dette trenger (tillegg kan man definerer felles konstanter). I typesterke språk må variabler være definert med en spesifikk datatype. Dvs. skal man lage en array må man si at det f.eks er en array av int-er og kan ikke si at den skal kunne inneholde int-er, float-er og tegn. Hovedgrunnen til å benytte seg av interface er derfor for å ha et sett funksjoner man kan bruke uten å vite hvilken klasse det er. For å ta et eksempel: Hvis vi ser bort fra PDO et øyeblikk kan man bruke databaser som et eksempel. Vi har ørten forskjellige databaser vi kan bruke i PHP. Mysql, postgresql, mssql osv. Skal man lage noe som skal brukes på flere database-systemer trenger man noe felles. Uten interface, arv e.l må man i typesterke språk «hardkode» hva man jobber med. Hvis man derimot sier at «en database består av disse funksjonene» vil man kunne si at man jobber med en database uten å egentlig vite hva som er bak. Hvis man ser litt på java igjen har vi ørten forskjellige komponenter. Det er veeeeeldig kjekt å kunne referere til de som JComponent i stedet for JLabel, JTextField, JTextArea osv. Det gjøre ting som lagring av de svært, svært enkelt (hvis man skal lagre en ubestemt sammensettning av de vel og merke). Altså man kan ha en array av JComponent i stedet for å ha en array med JLabel, en med JTextField, en med JTextArea osv. Enda et eksempel på hvor nyttig dette er er vinduer. Tenk deg at du skal ha ørten vinduer inni en applikasjon av forskjellige typer. Det er veldig kjekt å kunne referere til de som vinduer uten å vite hva de egentlig er og samtidig vite at de har funksjoner for å hente ut tittel, sette størrelse, velge om det er synlige osv. Abstrakte klasser Motivasjonen for å bruke abstrakte klasser mer mye lik den for interface. Man trenger en felles måte å aksessere forskjellige klasser uten å vite hva det egentlig er man jobber med. Hvis man drar databaser litt videre kan man tenke seg at man vil cache resultater (siden det fort kan være flaskehalsen i en applikasjon). Det å cache et resultat må kunne sies å være rimelig likt uavhengig av databasen. Det eneste man trenger en dataene fra spørringen pluss litt info om hvilken spørring det er (ink. data i spørringen) i tillegg til en funksjon for å hente ut og/eller sjekke om det finnes cache for en gitt spørring. Dette kan såklart gjøres i en vanlig klasse, men da kan jo også lage et objekt av klassen, og det går jo ikke. I tillegg blir det litt problemer med å definere de felles funksjonene. Her kommer abstrakte klasser inn. Da kan vi hente funksjonene fra interfacet, definere det som abstrakt (altså at de må defineres i subklasser) og i tillegg definere funksjonene for caching. Var det bedre tro? PS: Ja, det ble litt mye java-relaterte greier her, men som sagt, det gir umiddelbart litt mer mening i et typesterkt språk hvor du rett og slett MÅ definere hva ting skal være og ikke kan ha en array bestående av «hummer og kanari» uten at de har noe felles. Endret 22. mars 2008 av Ernie Lenke til kommentar
Peter Skrevet 23. mars 2008 Del Skrevet 23. mars 2008 Jeg bruker en del abstrakte klasser og interface i et prosjekt jeg holder på med nå. Det er flere ting som gjør at dette er hensiktsmessig: For det første skal det være et bibliotek, og det er enklere å forholde seg til objekter, klasser og metoder enn masse løse variabler og funksjoner. Selv om PHP ikke MÅ være et typesterkt språk, så støtter det noe som heter "type hinting" på mange områder. (Dvs. som parametere til funksjoner), noe som gjør at man kan "kreve" en egenskap/type. Gjenbruk av kode. Dersom en gruppe med klasser skal ha samme "grunnfunksjonalitet" så kan det være greit å legge dette i en "baseklasse" som alle disse klassene arver. Dette gjøres allerede implisitt i PHP ved at alle toppklasser (dvs. at de ikke bruker "extends") som opprettes automatisk arver "stdClass" som har metoden __toString(); For meg er det første og siste punkt som er viktigst. Dvs at det er enklere for å meg å spre dokumentasjonen som et grenesnitt/API de kan forholde seg til. Dessuten har veldig mange av klassene mine mye av den samme funksjonaliteteten. Lenke til kommentar
Rabbid Skrevet 23. mars 2008 Del Skrevet 23. mars 2008 (endret) Når vi er innom klasser; har et "problem" her: $foo = new Bar(); class fooBar{ function __construct(){ $foo->set('bar'); } } $Barfoo = new fooBar(); Hvordan kan jeg bruke $foo inne i klassen fooBar? Er altså en klasse jeg vil skal være tilgjengelig overalt. Endret 23. mars 2008 av Rabbid Lenke til kommentar
dabear Skrevet 23. mars 2008 Del Skrevet 23. mars 2008 (endret) objekter blir overført ved referanse (altså de blir ikke kopiert), så det skal gå bra å gi den til klassen vha av konstruktøren. $Barfoo = new fooBar($foo) altså. Alternativet er en singleton pattern, feks: http://www.developertutorials.com/tutorial...0729/page3.html Wikipedia har faktisk et godt eksempel på singleton patterin i php: http://en.wikipedia.org/wiki/Singleton_pattern#PHP_5 Endret 23. mars 2008 av dabear Lenke til kommentar
Rabbid Skrevet 24. mars 2008 Del Skrevet 24. mars 2008 (endret) Ble tipset om Singleton på IRC, ser ut til å være det jeg trenger, siden klassen skal være global. Endret 24. mars 2008 av Rabbid Lenke til kommentar
Ståle Skrevet 24. mars 2008 Del Skrevet 24. mars 2008 FInnes det et program for Windows som kan soke etter og erstatt ord i flere filer i en hel mappe? Fant et, men det slettet alle \t Lenke til kommentar
loathsome Skrevet 24. mars 2008 Del Skrevet 24. mars 2008 (endret) Skriv deg et PHP-script som gjør det, da vel Du er i PHP-pub nå. Endret 24. mars 2008 av loathsome Lenke til kommentar
Ståle Skrevet 24. mars 2008 Del Skrevet 24. mars 2008 Hadde vaert raskere med et C++ program feks. Men jeg tenkte at jeg gjerne kunne fa noen anbefalinger av noen her, iogmed at det er PHP det handler om. (Selv om det ikke bare er PHP-folk som bruker et sant program) Lenke til kommentar
jorgis Skrevet 24. mars 2008 Del Skrevet 24. mars 2008 Finnes vel kanskje en windows-port av sed? Lenke til kommentar
Garanti Skrevet 25. mars 2008 Del Skrevet 25. mars 2008 Går det an å lage under-arrays? Lenke til kommentar
Alex Moran Skrevet 25. mars 2008 Del Skrevet 25. mars 2008 (endret) <?php $array = array('bar' => array('test' => array(array(array(array()), array()), array(), array()), 'sports' => array()), 'foo' => array()); ?> Endret 25. mars 2008 av Ultraskarp Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå