[PHP][OO] Abstacte classes, overriding & type hinting

Pagina: 1
Acties:

Onderwerpen


  • RupS
  • Registratie: Februari 2001
  • Laatst online: 17-07 14:45
Ik heb een abstracte class en een extension ervan:
PHP:
1
2
3
4
5
6
7
class ValueObject {}

abstract class Dao {
  protected $dbConn,$resultset;

  abstract protected function insert(ValueObject $vo);
}

En vervolgens de extension:
PHP:
1
2
3
4
5
6
7
8
9
class UserDao extends Dao {
  public function insert(User $vo) {
    /* insert code */
  }
}

class User extends ValueObject {
  private $id,$name;
}

Als de insert methode in de extended class wordt aangeroepen moet er een user object worden meegegeven. Nu is het echter zo, dat je iedere willekeurige variabele er in zou kunnen gooien, zonder dat PHP daar over mekkert. Ik wil dus een vorm van type hinting toepassen met behoud van de abstracte beschrijving van de parent class.

Wat hierboven staat, werkt niet.
Foutmelding: Fatal error: Declaration of UserDao::insert() must be compatible with that of Dao::insert() in /usr/[......]

De geimplementeerde insert methode van het UserDao object wil nog steeds een ValueObject zien. Dit zou al een verbetering (halve type hinting is beter dan geen), alleen nog steeds niet erg strict. Nu is mijn vraag eigenlijk: kan dit, en zo ja, hoe? :)

Voor mijn gevoel heb ik nu de keuze:
- Abstract functions weglaten;
- Of niet (voor de helft) aan type hinting doen.
En dat vind ik niet voldoende, ik wil graag een vorm van allebei B)

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

Ik snap je denkwijze even niet. Waarom maak je een abstract als je je er vervolgens niet aan wilt/kunt houden? Je child is vervolgens niet meer 'compatible' met de abstract waar die van ge-extend is :?

  • RupS
  • Registratie: Februari 2001
  • Laatst online: 17-07 14:45
Ik maak de functie abstract om de implementatie verplicht te maken. Als dat zonder abstractie zou kunnen zou ik dat doen. ( of zo ... )

Echter wil ik naast die verplichting ook controleren wat er in een insert methode wordt gegooid. Als ik dat nu doe, komen inderdaad de insert functies niet overeen.

Is er een andere manier om dit voor elkaar te krijgen zonder ifjes binnen je function :)

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

RupS schreef op donderdag 25 augustus 2005 @ 14:46:
Ik maak de functie abstract om de implementatie verplicht te maken. Als dat zonder abstractie zou kunnen zou ik dat doen. ( of zo ... )
Precies :) Je wilt de implementatie verplicht maken van een insert functie die een ValueObject accepteert. Vervolgens ga je die veranderen in je child, waardoor die hele verplichtheid vrij nutteloos wordt.

Een interface is hier misschien meer op z'n plaats. De insertfunctie laat je dan een object accepteren die 'insertable' is bijvoorbeeld.

[ Voor 4% gewijzigd door Bosmonster op 25-08-2005 15:13 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Je kunt idd niet de interface van DAO aanpassen. Je moet er aan voldoen. Dit is geen halve typehinting trouwens, dit is gewoon normaal in een OO taal. Je zult in een strong typed taal in zo'n geval eerst moeten casten naar het juiste type. In php hoef je niet te casten dus dat kun je overslaan.

Ik had hier laatst ook een topic over geopend: [rml][ OOP] Is casten te voorkomen (bij een framework)?[/rml]

Je houd echter wel problemen met types. Het is gewoon nu eenmaal niet geheel type safe.

[ Voor 11% gewijzigd door Michali op 25-08-2005 15:08 ]

Noushka's Magnificent Dream | Unity


  • RupS
  • Registratie: Februari 2001
  • Laatst online: 17-07 14:45
Juist, wat ik al vermoedde dus...
Ik heb nu het type hinting zwaarder laten wegen, dus dat voer ik in alle extended objecten door. In de abstract class heb ik de insert (en andere methods die een $vo willen) abstract weggehaald, en gooi ik nu een exceptie dat de methode niet geimplementeerd is. Ik denk dat het in dit geval het "netst" is.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
abstract class Dao {
  protected $dbConn,$resultset;

  protected function insert(ValueObject $vo) {
    throw new Exception('Function not implemented');
  }
}
class UserDao extends Dao {
  function insert(User $vo) {
    /* doe andere dingen */
  }
}


Zo kun je nog zien welke methodes je moet implementeren en kan ik toch type hinting doorvoeren in de andere Dao methodes.

edit:

voorbeeldje verduidelijkt

[ Voor 17% gewijzigd door RupS op 25-08-2005 23:12 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Ik zie niet waarom terug gaan naar php 4 methodes je probleem ook maar enigzins oplost :? Je kunt nu nog steeds de interface van insert() niet aanpassen in subclasses. Dat hij eerst abstract was heeft daar niets mee te maken.

Overigens zou ik (zoals bosmonster ook al zei) van ValueObject gewoon een interface maken. Beter nog is om die interface geheel weg te laten. Het is beter om je domein objecten (aangenomen dat je volgens zo'n manier werkt) zo veel mogelijk los te houden van je Data Access code (en andere onderdelen uiteraard). Het implementeren van een lege interface of class heeft iig geen voordeel hier.

Noushka's Magnificent Dream | Unity

Pagina: 1