[oop] class instantiëren blokkeren
Ik heb een class met daarin een paar constant values. Verder doet die class niks, en daarom wil ik voorkomen dat de class geinstantieerd kan worden.
Volgens mij zijn daar 2 manieren voor:
- de class abstract maken, óf...
- een private constructor in de class zetten
Heeft een van deze methodes een voorkeur? Maakt het iets uit? Of is er nog een andere manier?
Voel je nu niet aangevallen, maar ik ontdek de laatste tijd erg in jouw vragen dat jij je applicatie heel erg wilt limiteren. Je wilt dat alles alleen uitgevoerd/gebruikt kan worden op de manier die je nu in je hoofd hebt. Uit ervaring, die jij waarschijnlijk wel kan delen, weet ik dat ik over hetzelfde problem over een paar maanden compleet anders denk. Ik zou dus iedereen altijd aanraden een applicatie zo open mogelijk te schrijven, "Open for extension, closed for modification" zoals het open/closed-principe zo mooi zegt.
Dankjewel voor het meedenken. Je hebt daar wel een punt. Echter, omdat ik er zeker van ben dat er verder met deze class niks gaat gebeuren en het zinloos is om 'm te instantiëren vind ik het netter om 'm dicht te gooien. En misschien heb je gelijk dat ik er over een paar maanden anders over denk, maar voor nu wil ik 'm dichtmaken :) Alleen de vraag is dus wat de beste manier daarvoor is. Abstract is van de ene kant netter omdat ik dan geen constructor in m'n class heb staan. Maar als ie abstract is kun je m wel weer extenden :-s
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
final abstract class MijnMagJeNietGebruiken
{
const MIJ_WEL = 'Ja, ikke wel!!!';
final abstract private function __construct() {}
final abstract private function __wakeUp() {}
final abstract private function __sleep() {}
final abstract private function __clone() {}
final abstract private function __call() {}
final abstract private function __callStatic() {}
final abstract private function __get() {}
final abstract private function __set() {}
final abstract private function __destruct() {}
}
?>
final abstract class MijnMagJeNietGebruiken
{
const MIJ_WEL = 'Ja, ikke wel!!!';
final abstract private function __construct() {}
final abstract private function __wakeUp() {}
final abstract private function __sleep() {}
final abstract private function __clone() {}
final abstract private function __call() {}
final abstract private function __callStatic() {}
final abstract private function __get() {}
final abstract private function __set() {}
final abstract private function __destruct() {}
}
?>
Gewijzigd op 22/04/2014 20:19:31 door Wouter J
On-topic. Om instantiëren te voorkomen. Abstract of private constructor?
Zijn het echt alleen maar een paar constante die je in een class hebt staan? Geen static methods?
Want dan zou ik gewoon constante defineren in een namespace. Dat is wat je wilt berijken door een class te hacken: constanten in een namespace stoppen. Stop in dat geval de constante gewoon in een namespace!
Ozzie\WeekDays::MONDAY vs Ozzie\WeekDays\MONDAY
PHP 5.6 heeft wel een coole nieuwe feature: http://3v4l.org/4peGi
Ja inderdaad!
>> Zijn het echt alleen maar een paar constante die je in een class hebt staan?
Ik snap ff niet hoe dat werkt eigenlijk... Ik kan toc niet automatisch een namespace laden?
Emhe... zou je de tweede quote kunnen vervangen door de correcte quote? Ik weet niet waar je het nu over hebt.
Die zat nog onder de ctrl-v knop :)
Het ging hier om:
>> Stop in dat geval de constante gewoon in een namespace!
Ik kan toch niet automatisch een namespace laden?
Tot PHP 5.6 kun je alleen classes/interfaces/traits importeren met het use keyword. https://wiki.php.net/rfc/use_function Heeft dat voor PHP 5.6 veranderd: je kunt functies en constanten ook importeren met het use keyword.
Is dat waar je het over had?
Even een voorbeeldje om het idee duidelijk te krijgen. Ik wil ergens een language instellen aan de hand van constanten die in een language class staan. Dus zeg maar zoiets als dit:
Code (php)
En dan wil ik dit kunnen doen:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
use user\preference\preferences;
use language\language;
$user_preferences = new preferences();
$user_preferences->setLanguage(language::NL);
?>
use user\preference\preferences;
use language\language;
$user_preferences = new preferences();
$user_preferences->setLanguage(language::NL);
?>
Die language class bevat alleen maar een aantal constanten, en daarom moet die class niet geinstantieerd kunnen worden.
Gewijzigd op 22/04/2014 21:55:49 door Ozzie PHP
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
use user\preference\preferences;
use language;
$user_preferences = new preferences();
$user_preferences->setLanguage(language\NL);
?>
use user\preference\preferences;
use language;
$user_preferences = new preferences();
$user_preferences->setLanguage(language\NL);
?>
Tada!
Maar... ik ben ff kwijt hoe ik dit nu moet inladen :-s
Ik gebruik een autoloader om classes te loaden.
Hier wordt de language class dus automatisch geladen.
$user_preferences->setLanguage(language::NL);
Maar hoe doe ik dat dan in jouw situatie? Ik kan die namespace toch niet automatisch laden?
Constants in interfaces werken weldegelijk. Misschien eerst testen voordat je een perfect antwoord naar de prullenbak verwijst?
Die heb ik gisteren getest en toen deed ie het niet. Net nog een keer getest en nu doet ie het wel. Ik vermoed dat ik dus gisteren ergens een echo ben vergeten.
Dus ondanks dat ik je opmerking in eerste instantie totaal niet begreep... toch bedankt :)
En Ward ook bedankt!
Graag gedaan, ik wilde al vragen waarom je zo reageerde ;-)
Ik had het getest, maar ik denk echt dat ik de echo ben vergeten. Anyhow... gelukkig was Wouter nog daar om me even wakker te schudden.
Al met al een mooie en prima oplossing! :)