Abstract methodes door laten erven
Dit is een voorbeeld van een classe hierarchy dat ik wil berijken.
Ik weet alleen niet of dit "professioneel" mogelijk is.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
abstract class Connection{
abstract function error();
}
class FTP extends Connection{
private $pError;
function error(){
return $pError;
}
}
interface iDatabase{
function query( $sql );
// en nog een hele waslijst met standaard methodes.
}
abstract class Database extends Connection{
abstract function error(); // Here, it shall error. Function must contain body, Noooh!
}
class MySQL extends Database implements iDatabase{
function error(){
return mysql_error();
}
function query( $sql ){
return mysql_query( $sql );
}
}
class MySQLi extends Database implements iDatabase{
function error(){
return mysqli_error();
}
function query( $sql ){
return mysqli_query( $sql );
}
}
class PostGreSQL extends Database implements iData //... etc
?>
abstract class Connection{
abstract function error();
}
class FTP extends Connection{
private $pError;
function error(){
return $pError;
}
}
interface iDatabase{
function query( $sql );
// en nog een hele waslijst met standaard methodes.
}
abstract class Database extends Connection{
abstract function error(); // Here, it shall error. Function must contain body, Noooh!
}
class MySQL extends Database implements iDatabase{
function error(){
return mysql_error();
}
function query( $sql ){
return mysql_query( $sql );
}
}
class MySQLi extends Database implements iDatabase{
function error(){
return mysqli_error();
}
function query( $sql ){
return mysqli_query( $sql );
}
}
class PostGreSQL extends Database implements iData //... etc
?>
Dit is alleen niet mogelijk omdat "Database" een body verwacht op de methode error.
Is er een mogelijkheid om dit wel te laten werken, zonder daarvoor nog een andere methode te maken en door te linken zoals "getError()",
Door personelijke onstandigheden heb ik momenteel thuis geen Internet, ik heb alleen de mogelijkheid om dit op een andere locatie te doen, dus verwacht niet per direct antwoord.
Alvast bedankt.
Gewijzigd op 19/05/2010 10:24:12 door Johan K
Mijn PHP (5.3.nogwat) geeft een iets duidelijkere foutmelding: PHP Fatal error: Can't inherit abstract function Connection::error() (previously declared abstract in Database). En inderdaad, wanneer ik Connection::error weglaat dan gaat het goed. Die eis dat alle classes die Database extenden een method genaamd error() moeten hebben zit al in Connection. En die eis kan je niet overschrijven.
Grappig dat je dit ook even heb uitgetest, heb deze code met de losse hand geschreven. Had wel een syntax errortje verwacht.
Ik begrijp deze error wel, ik moet een body "{}" op de error methode in classe Database declareren, maar dan kan de methode niet overschreven worden, toch? Ik had namelijk wel iets gelezen over de final keyword.
Ik begin de laatste tijd echt in te zien hoe handig het verlengen van een classe is, dus ik weet er nog niet alle "tricks".
En bedankt voor je snelle reactie, ik ga het thuis even proberen want ik had niet verwacht dat hij geen error zou geven als hij gedeclareerd is in de kinderen van Database.
Misschien nog iets, bestond of bestaat er nog ergens een optie in PHP zoiets als "required"?
Dus dat deze classes eventueel worden geladen standaard met __autoload, voordat ze daadwerkelijk gebruikt worden.
Zou handig zijn voor error handeling classes, met set_*_handler(array( 'class', 'static method' ) );
Gewijzigd op 19/05/2010 10:38:53 door Johan K
Als Database abstract is, hoef je de method niet te voorzien van een body. (mits je er het abstract keyword voor zet) Maar een class die Database extends, PgSQL bijv, en die niet abstract is, moet wel aan alle eisen voldoen. En die moet dus wel een method error met een body hebben.
PS: Gebruik je PHP 6, of gewoon de laatste build van PHP's trunk? Want PHP 6 zelf is op het moment niet in ontwikkeling. Volgens mij is de trunk tegenwoordig weer gebaseerd op PHP 5.3.
En persoonlijk weet ik niet precies wat voor build het is, thuis heb ik geen Internet, dus ik had aan een vriend van mij gevraagd of hij het even op een jumpdrive kon zetten, en simpelweg gewoon geinstalleerd. Hij zei dat het versie 6 was, dus daarop vertrouwde ik op.
Ik zal wel voor je kijken, maar daar kan ik vandaag geen antwoord op geven.
Gewijzigd op 19/05/2010 10:47:48 door Johan K
Op dit moment is er nog geen beslissing gemaakt over de volgende versie van PHP. Het kan 5.4 zijn, 6.0 maar ook 7.0. Heeft onder andere te maken met Unicode support wat een beetje drama is geworden binnen het ontwikkelteam.
Waarschijnlijk heb je dus gewoon een snapshot van de trunk.
Deze informatie weet ik via de internals list van PHP. Heb dus niks met de ontwikkeling ervan te maken :)
Verder ontopic:
Je implement overal iDatabase, maar voor zover ik nu zie is het logischer om de abstracte class iDatabase te laten implementeren.
Over het 'final' keyword. Als je een class maakt, met een final method, kan je bij een extend van die class, die specifieke method niet overrulen. Je kan ook een complete class dus final maken, zodat van die class geen extend gemaakt kan worden,