Avatar billede junold Nybegynder
23. april 2008 - 08:54 Der er 11 kommentarer og
1 løsning

Nedarvning og indkapsling i PHP - Forklar venligst!

Jeg har lidt forvirring mht arv i PHP. Hvornår arver noget i PHP?
Er det kun, ved en agregering (som jeg har forstået, er en klasse der indeholder klasser)? Eller hvad? Eller kun hvis man skriver f.eks. "class a extends class b" at så arver b, eller arver den fil, hvor man includer en klasse?

Og med indkapsling? Er det rigtigt hvad jeg siger i http://www.eksperten.dk/spm/828728? For jeg synes ikke f.eks. Global virker helt på den måde...

Jeg er lidt forvirret i det her, håber nogen kan gøre rede for det.
Avatar billede rax Praktikant
23. april 2008 - 13:10 #1
Nedarvning i OOP sker i det øjeblik, du explicit vælger at en klasse skal nedarve fra en anden.

I dit eksembel

class A extends B
{
  ...
}

nedarver klasse A samtlige public og protected felter og metoder, og kan derfor tilgå disse.

Mht. indkapsling, så er du på rette spor i din anden tråd. private og public access anvendes netop til at sikre en indkapsling, således at private indhold kun kan tilgås via public metoder (og Properties, som vidst nok ikke er en del af OOphp endnu).
Målet med indkapslingen er at skabe to ting:

1) Løs kobling (loose coupling)
Dette vil sige, at klassens indhold kun kan tilgås via accessor (get) og mutator (set) metoder. Tommelfingerreglen er her, at felter erklæres private, mens tilgangsmetoderne erklæres public.

2) Stærk binding (strong cohesion)
Dette princip indebærer, at den enkelte metode kun skal koncentrere sig om én opgave, og ikke alle mulige andre opgaver. Disse flyttes til selvstændige metoder, som navngives intuitivt.

Indkapslingen er med til at sikre en utrolig letlæselig og vedligeholdelsesvenlig modulering af koden, som gør det nemt at tilføje, ændre og fjerne funktionalitet, og samtidig medfører, at ændringer som oftest kun skal foretages ét sted.

"global" som accessor i forbindelse med metoder kender jeg ikke noget til.. global keywordet anvendes til at give en function adgang til variable erklæret uden for funktionen, idet funktioner ikke som udgangspunkt kan se ud over deres eget afgrænsede område.

Jeg håber dette gav noget afklaring :) ellers er du meget velkommen til at skrive igen. Jeg kan også anbefale noget litteratur, både dansk og engelsk, som kan understøtte OOP.

- Kristian
Avatar billede junold Nybegynder
23. april 2008 - 14:53 #2
Okay, har du lyst til lige at læse det jeg har skrevet igennem? Det er her...
http://www.click2create.dk/lidt%20om%20klasser.docx

Af en eller anden grund, laver IE den om til .zip når man henter den, men bare omddøb den til .docx

Jeg vil meget gerne se det litteratur på dansk!
Avatar billede g1mzee Nybegynder
23. april 2008 - 15:38 #3
ser godt ud :).
Men er det en opgave du laver eller?
Avatar billede junold Nybegynder
23. april 2008 - 15:50 #4
Ja, det er til en opgave.. Det er et udsnit af opgaven. Skal nok lige skrives ren, men super hvis i har kommenterer/rettelser!
Avatar billede rax Praktikant
23. april 2008 - 15:56 #5
hmm, på hvilket niveau og i hvilken forbindelse skriver du denne opgave?
anyway, har skimmet den super hurtigt (er på arbejde :P), og har lige et par kommentarer:

side 1: "Helle Jørgensen" er egentlig ikke en klasse, i den metaforiske tankegang du udlægger. En "Ansat" ville derimod være en klasse, mens "Helle Jørgensen" ville være et objekt instantieret af denne klasse.

side 3: hmm, jeg er faktisk ikke sikker på, at protected kun lader tilgang ske ét niveau under.. jeg ville mene, at det gælder hele vejen ned igennem det nedarvede hierarki.

side 4: der behøves ikke at oprette objekter af de klasser man nedarver fra, for at få adgang til de nedarvede metoder og attributter.. dog skal man kalde konstruktøren på den klasse, man nedarver fra. Dette gøres som regel med et reserveret ord. Kan ikke lige huske, hvorledes det gøres i PHP.

Hvad angår litteratur, så vil jeg anbefale Lars Mathiasen et. al. Objektorienteret Analyse & Design, til forståelse af objektorienteret systemudvikling. Bogen fås både på dansk og engelsk, og er skrevet af danskere. Det er en ret god bog, som giver et grundigt indblik i OOP og UML. Har selv læst den i forbindelse med studie, samt undervist i den, så kan godt stå inde for den :)
Avatar billede junold Nybegynder
23. april 2008 - 16:08 #6
Det er på H9 som datafagteknikker.

Har prøvet at rette den metaforiske lidt. Kan godt se fejlen.. "Helle" og "jørgensen" er så hendes attributter, der er fornavn og efternavn ikke?

Det på side 3.. Hvis protected tillader arv hele vejen ned, hvad gør public så? Er det så på den måde, at det kun er ting der er public der kan kaldes gennem objektet?

På side 4.. er det dette du mener?

$objUsers = new users;
Echo $objUsers->$errors;

Der mener jeg, hvis $errors skal bruges uden for klassen users, skal man lave et objekt...

Jeg har lidt svært ved det med klasser og objekter, så det er super med noget hjælp. Synes det er svært at få det helt på det rene.
Avatar billede rax Praktikant
23. april 2008 - 18:44 #7
hehe, du er da på rette vej :)

- jo, "Helle" og "Jørgensen" vil være værdierne af atributterne fornavn og efternavn, hhv. En klasse kan opfattes som en skabelon, som man kan skabe objekter ud fra.

- protected mener jeg helt klart tillader nedarvning hele vejen ned igennem et hierarki. public betyder, at det dels kan tilgås i det øjeblik man befinder sig i klassen, har oprettet en instans af klassen, eller hvis man nedarver fra klassen. protected kan kun tilgås, hvis man befinder sig i klassen, eller nedarver fra den.. altså ikke ved blot at oprette et objekt af klassen.

- jo, det er det jeg mener. Dog kan du kun udskrive $errors på den måde, hvis $errors er erklæret public, hvilket er en dum idé, jf. diskusionen om indkapsling. Istedet bør $errors være erklæret private, og der bør erklæres en public get-metode til at tilgå variablen, som vist her:

class users
{
  private $errors = "fejl";

  public function getErrors()
  {
    return $errors;
  }

}


class SomeOtherClass
{
  $objUsers = new users;
  echo $objUsers->getNavn();  // udskriver "fejl"
}


Håber det hjalp :)
Avatar billede junold Nybegynder
23. april 2008 - 19:10 #8
Det har hjulpet super meget! Tror jeg er ved at have styr på det nu! Ærgerligt jeg ikke når at få fat i den bog før uddannelsen er slut, for det er jo nu. H9 er sidste forløb.

Men mange tak for god viden, og gode forklaringer! :)
Avatar billede junold Nybegynder
23. april 2008 - 19:37 #9
Har lige et sidste spørgsmål. Hvorfor laver man en løs kobling, frem for at sætte eller hente attributten direkte?

Går ud fra at den stærke binding laves, for at gøre det mere overskueligt. Her kan man jo meget lettere se "hvem laver hvad." Så har man f.eks. en metode til hentning af data, en til skrivning, en til sletning osv...?
Avatar billede rax Praktikant
24. april 2008 - 09:15 #10
Det var så lidt :) og hvis du kommer til at beskæftige dig med systemudvikling, så vil du helt sikkert have glæde af at have fået en forståelse for stoffet :) bemærk dog, at bogen på ingen måde knytter sig til noget specifikt sprog, men omhandler OOP generelt.

Du har helt ret i, at den stærke binding opretholdes dels for at gøre koden mere overskuelig, men også dels for at opdele programmet i så mange "legoklodser" som muligt, så enkelte funktionaliteter nemt kan tilføjes/fjernes/ændres.

Den løse kobling ønsker man at opretholde, for at gøre de enkelte klasser uafhængige af, hvordan de andre klasser fungerer internt. En klasse bør vide, HVAD en anden klasse gør, men ikke HVORDAN den gør det. Dette gør, at man kan ændre lige så tosset i en klasse som man vil, og stadig sikre sig, at andre klasser som bruger klassen stadig vil fungere, så længe man ikke ændrer på de public tilgangsmetoder. Et lille hurtigt tænkt eksempel:

class A
{
  public function getData()
  {
    // opret forbindelse til en database, hent data ud, og returner det.
    ...
    return $data;
  }
}

class B
{
  $a = new A();

  public function udskrivData()
  {
    $data = $a->getData();

    print($data);
  }
}

Forestil dig nu, at jeg i klasse A vælger at lave min getData() metode om til istedet at hente dataen fra en XML fil, fra en tekstfil eller evt. via et WebService kald.. Det kan jeg frit gøre uden komplikationer for klasse B, idet klasse B kun behøver at vide, at man kan kalde getData() for at få fat i noget data.. hvordan klasse A internt anskaffer sig den data, er fuldstændigt uvedkommende for klasse B. Det er - så at sige - indkapslet i klasse A. Dette er et eksempel på løs kombling.

- kristian
Avatar billede rax Praktikant
24. april 2008 - 09:18 #11
hov, i klasse A manglede jeg naturligvis at erklære et felt:

private $data;

og i klasse B glemte jeg at erklære $a private:

private $a = new A();

.. oh well, det er tidligt om morgenen, og solen skinner :D
Avatar billede rax Praktikant
24. april 2008 - 09:18 #12
tak for point i øvrigt :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester