Nu is deze vraag al waarschijnlijk 100 keer gesteld. Maar ik krijg het er bij mij zelf niet in waarom ik OO moet gaan gebruiken.

Ja, ik zie het voordeel van Object oriented programmeren. Maar ik zie niet waarom ik Classes moet gebruiken. Nu heb ik in de tijd dat ik van OO afweet in PHP tot nog toe nooit een echt groot project gehad waarvan ik zeg dat OO echt nodig is.

Nu ben ik echter bezig met een tool, waarbij ik echt volgens mij doen al OO werk, maar niet het voordeel zie van Classes etc...

Als ik dan zoek naar Waarom OO? krijg ik het antwoord "omdat je bepaalde functies kan her gebruiken" Dan kom ik eigenlijk tot de conclusie dat ik al OO denk wanneer ik bijvoorbeeld een centraal bestand heb met daarin functions die ik dus hergebruik.
Ook omdat ik bijvoorbeeld voor een inlog scherm al het bestand inlog.php include. (ik noem maar wat)en die aanpas als er wat moet gebeuren...


Nu ben ik dus niet opzoek waarom OO, maar ik ben eigenlijk opzoek die bij mij de knop kan omzetten om OO te gaan programmeren met de bijbehorende objecten, classes etc.


Ik kom ook nooit uit het voorbeeld van de auto... Boeiend dat deze blauw moet zijn...
Graag hoor ik het ook als ik echt compleet de bus mis en bovenstaande kant noch wal raakt.. Ik probeer bij mij zelf die knop om te zetten....
Dos, laat ik m'n vraag anders stellen. Waarom wordt in het voorbeeld met phonenumber gesteld dat je beter een interface kunt gebruiken dan een abstracte class? Als de child class de abstract class extends dan is de child class al zo goed als klaar. Dan hoef je daar alleen de validate method in te zetten. Terwijl als je geen gebruik maakt van een abstract class en de child class een interface laat implementeren, dan moet je de hele class opnieuw opbouwen. Dat verschil snap ik niet. Wanneer maak je een method abstract? Mijn gedachte: wanneer deze method ook moet voorkomen in de child class.
In zowel een abstracte klasse als een interface is het zo dat de child klasses die hier gebruik van maken de (abstracte)methoden moeten implementeren.

Even een heel simpel voorbeeldje.

<?php
interface pizza {

public function prepare();
public function bake();
public function slice();
public function serve();
}

class funghiPizza implements pizza {

private $ingredients;

public function __construct($ingredients) {

// minimaal een paar ingredienten meegeven want van alleen 1 ingredient kunnen we geen pizza maken. :p
if(is_array($ingredients)){

foreach ($ingredients as $ingredient) {
$this->ingredients[] = $ingredient;
}

return $this->ingredients;

}
else {
throw new InvalidArgumentException('No error given: ' . $ingredients);
return false;
}

}

public function prepare() {
$this->gooihetindeblender();
}

public function bake() {
// etc
}

public function slice() {
// etc
}

public function serve() {
// etc
}

}

abstract class pizza {

public function __construct($ingredients) {
// minimaal een paar ingredienten meegeven want van alleen 1 ingredient kunnen we geen pizza maken. :p
if(is_array($ingredients)){

foreach ($ingredients as $ingredient) {
$this->ingredients[] = $ingredient;
}

return $this->ingredients;

}
else {
throw new InvalidArgumentException('No error given: ' . $ingredients);
return false;
}

}

public function prepare() {

$this->gooiErEierenIn();

}

public abstract function bake();
public abstract function slice();
public abstract function serve();

}

class rarePizza extends pizza {

public function __construct() {
parent::__construct();
}

public function bake() {

}

public function slice() {

}

public function serve() {

}

}



?>

Zoals je hier zit kan ik bij de interface welke pizza dan ook maken en alles gebruiken en doen of laten wat ik ermee wil. Bij de abstracte klasse wordt dit al gauw beperkt omdat in dit geval de prepare methode bepaalt hoe een pizza gemaakt wordt en naar mijn idee hoort een pizza anders gemaakt te worden dan een andere pizza. Het gebruik van interfaces is beter dan een abstracte klasse te gebruiken omdat je meer controle hebt over wat een child klasse moet doen.

Hier wil ik niet mee zeggen dat een abstracte klasse nu de boeman is en niet gebruikt moet worden want ook deze heeft zijn voordelen maar dat hangt af per geval. Een abstrace klasse zou ik eerder gebruiken wanneer ik bijvoorbeeld een klasse person maak en dan een klasse Werknemer die bijv setName, getName etc moet overerven

[size=xsmall]Toevoeging op 28/11/2013 13:33:40:[/size]

Ozzie PHP op 28/11/2013 13:09:53

Dos, laat ik m'n vraag anders stellen. Waarom wordt in het voorbeeld met phonenumber gesteld dat je beter een interface kunt gebruiken dan een abstracte class? Als de child class de abstract class extends dan is de child class al zo goed als klaar. Dan hoef je daar alleen de validate method in te zetten. Terwijl als je geen gebruik maakt van een abstract class en de child class een interface laat implementeren, dan moet je de hele class opnieuw opbouwen. Dat verschil snap ik niet. Wanneer maak je een method abstract? Mijn gedachte: wanneer deze method ook moet voorkomen in de child class.


Moet het bij een interface dan niet voorkomen in de childklasse? ( Jazeker wel ) alleen is de vrijheid die je hierbij krijgt dat jij het aan de child overlaat hoe hij/zij deze invult en niet de implementatie klakkeloos overneemt zie mijn voorbeeld hierboven.
Een methode uit een interface kun je niet implementeren als een abstracte methode. Probeer het maar en voeg abstract public function setAmount($amount); toe:

Fatal error: Can't inherit abstract function PaymentInterface::setAmount() (previously declared abstract in AbstractPayment)

Het voorbeeld werkt dan alleen nog als we de interface overboord gooien. Het lijkt daarmee een keuze en dan verkies ik de interface. Je kunt anders helemaal geen interface meer implementeren. Je zit vast aan een extends van de abstracte klasse, ook als je geheel andere klassen wilt bouwen met dezelfde interface.

Op dat laatste komt het aan: de interface formaliseert slechts de API van klassen, een abstracte klasse is al gedeeltelijk een implementatie.
Pfff, lastig dit.

@Reshad: terug naar jouw pizza voorbeeldje dan. Ik zou zeggen dat iedere pizza in een restaurant op dezelfde manier wordt gebakken, gesliced en geserveerd. Bij het bakken verschilt hooguit het aantal minuten, maar het in stukken snijden en het serveren gebeurt op dezelfde manier. Ik ga er vanuit dat alle pizza's door een ober worden geserveerd en dat niet een pizza margherita ineens door een olifant wordt opgediend. In mijn optiek zijn de methods bake, slice en serve dus onderdeel van de abstract class. Aan de functie prepare moet per pizza een eigen invulling worden gegeven dus die maken we abstract. Dan krijgen we dus dit:

<?php

abstract class pizza {

protected $ingredients;

public function __construct($ingredients) {
// set the ingrediƫnten als class properties
}

abstract public function prepare(); // de prepare method verschilt per pizza, dus abstract!

public function bake() {
// stop de pizza in de oven en bak 'm
}

public function slice() {
// snij de pizza in stukken
}

public function serve() {
// serveer de pizza
}

}

?>
En dan de pizza zelf:

<?php

class PizzaSiciliana extends Pizza {

public function prepare() {
// bereid de pizza voor
}

}

?>
Dit is toch hoe het zou moeten?????

(P.S. je kunt geen waarden returnen in een constructor zoals jij in je voorbeeld doet)

[size=xsmall]Toevoeging op 28/11/2013 13:55:39:[/size]

Ward van der Put op 28/11/2013 13:35:16

Je kunt anders helemaal geen interface meer implementeren. Je zit vast aan een extends van de abstracte klasse, ook als je geheel andere klassen wilt bouwen met dezelfde interface.

Maar de vraag is in hoeverre het instellen van een telefoonnummer of een amount beschouw moet worden als een interface, of als onderdeel van de blauwdruk van de class. Dat vind ik nogal lastig te bepalen. Als ik jouw redenatie volg dan zouden er in jouw abstracte classes nooit abstracte methods te vinden zijn.

Op deze link: http://stackoverflow.com/questions/1913098/what-is-the-difference-between-an-interface-and-abstract-class


Abstract classes look a lot like interfaces, but they have something more : you can define a behavior for them. It's more about a guy saying "these classes should look like that, and they got that in common, so fill in the blanks!".

Dat is wat ik bedoel. De hele class om het telefoonnummer of de betaling of de pizza in te stellen of maken is er al. Je moet alleen even de gaten opvullen, ofwel die ene method: setPhoneNumber, setAmount, of preparePizza.
Dos Moonen op 28/11/2013 13:57:26

@ward Het werkt prima op ondersteunde PHP versies:
http://sandbox.onlinephpfunctions.com/code/6fb652c5c012313514cff127b8a556293f69ede4
5.3.3 geeft die foutmelding van jou, 5.3.10 (er zit niets tussen) slikt het wel.
PHP 5.3 is niet meer ondersteund en negeer ik persoonlijk lekker.
Oh, fijn is dat. Was dat een ordinaire bug? Of meer een ongelukkige keuze voor de gelijktijdige implementatie van een abstracte klasse en een interface?
Ward van der Put op 28/11/2013 14:03:44

[quote="Dos Moonen op 28/11/2013 13:57:26"]
@ward Het werkt prima op ondersteunde PHP versies:
http://sandbox.onlinephpfunctions.com/code/6fb652c5c012313514cff127b8a556293f69ede4
5.3.3 geeft die foutmelding van jou, 5.3.10 (er zit niets tussen) slikt het wel.
PHP 5.3 is niet meer ondersteund en negeer ik persoonlijk lekker.
Oh, fijn is dat. Was dat een ordinaire bug? Of meer een ongelukkige keuze voor de gelijktijdige implementatie van een abstracte klasse en een interface?
[/quote]
Niet verder gezocht dan dat. Ik vermoed een ongelukkige keuze.
Kunnen jullie aub nog reageren op mijn 2 voorgaande berichten?
Ozzie PHP op 28/11/2013 13:52:54

@Reshad: terug naar jouw pizza voorbeeldje dan. Ik zou zeggen dat iedere pizza in een restaurant op dezelfde manier wordt gebakken,

Nee, je kan bijvoorbeeld denken aan de pizza's in de pizzahut. Daar heb je steen oven pizza's en pan pizza's. Niet hetzelfde dus, gaan niet door hetzelfde proces.
Ozzie PHP op 28/11/2013 13:52:54

gesliced

Nee, een pizza calzone snijdt je niet in stukken, die serveer je als geheel.
Ozzie PHP op 28/11/2013 13:52:54

en geserveerd.

Nee, een afhaal pizza wordt niet geserveerd, maar in een doos gepropt en afgegeven.

Met andere woorden, hier wil je een interface gebruiken, omdat alle pizza's in essentie dezelfde stappen doorlopen, maar zeker niet op dezelfde manier. Een absbtracte klasse heeft dus geen toegevoegde waarde.

Reageren