| 

.NET C# Java Javascript Exception

2
Hey Leute,
Ich will mir ein wenig Tipparbeit sparen und versuche folgendes:

class Main {
protected $_data;

static public function getOptions()
{
return self::$_data;
}
}



class Variant extends Main{
protected $_data = array(
'key' => 'value',
'key2' => 'value2',
'key3' => 'value3',
);

}



Nun möchte ich wie folgt darauf zugreifen: Variant::getOptions()... Nur leider funnktioniert das nicht.

Ich würde gerne vermeiden die Methoden nicht statisch zu machen, da ich nicht jedes mal
eine neue Variable für eine Instanz der Variant erstellen will:
//NICHT SO
$variant = new Variant();
$variant->getOptions();

Hoffe jemand hat ne Lösung parat?

Viele Grüße
24.01.2013
spiike 170 1 7
spiike 170 1 7
5 Antworten
1
Man kann zwar die static Variablen in Kind-Klassen überschreiben, aber die Methode getOptions() wird im Kontext von Main ausgeführt, auch wenn sie über eine Kind-Klasse aufgerufen wird. Damit ist self::$_data gleichbedeutend wie Main::$_data.

In einer Idealen OOP-Welt dient Vererbung nicht direkt der Vermeidung von Tipp-Arbeit, sondern um eine Beziehung zwischen Eltern- und Kind-Klasse zu beschreiben.

Wenn es nur darum geht Tipparbeit einzusparen, dann würde ich das über Helper-Klassen lösen, so spontan fällt mir da das Regestry-Pattern ein, aber das ist auch nicht ganz sauber.

Ich gehe mal davon aus, dass es sich bei den ca. 30 Klassen um Konfigurationen handelt, dann fände ich das Regestry-Pattern vertretbar.

class Configuration {
protected static $configuration = array();

public static function getOptions($name) {
return self::$configuration[$name];
}

public static function setOptions($name, $values) {
self::$configuration[$name] = $values;
}

}

Configuration::setOptions('A', array('a' => 1, 'b' => 'drei'));
Configuration::setOptions('B', array('b' => 70, 'c' => 'eins'));

print_r(Configuration::getOptions('A'));
echo "\n\n";
print_r(Configuration::getOptions('B'));
echo "\n\n";


Aber wirklich Tipparbeit spart das nur, wenn Du den Rückgabewert von getOptions() immer als Array verwenden kannst, da php keine Aufrufe der Form Configuration::getOptions('B')['b'] zulässt (Syntax-Error). Das geht nur über den Umweg

$b = Configuration::getOptions('B');
echo $b['b'];
24.01.2013
phg 1,6k 3
Sauber genau das brauchte ich!
spiike 24.01.2013
Wie gesagt, so ganz sauber ist das Regestry-Pattern nicht ;)
phg 24.01.2013
Aber warte mal...

Du hast schon recht, ich möchte verschiede Configurationen damit steuern.

Geh mal von Select-Feldern aus:
Klasse Geschlecht extends StaticMethods
die Methoden sollen in "StaticMethods" deklariert werden, aber in Geschlecht sollen die Daten gesetzt werden. Wie soll ich das dann mit deiner Methode machen?
spiike 24.01.2013
Bei dem Regestry-Ansatz wird eben keine Vererbung verwendet. Statt Geschlecht extends StaticMethods müsstest Du StaticMethods::setOptions('Geschlecht', array(...)); schreiben.

Ich bekomme gerade das ungute Gefühl, dass wir eine etwas unterschiedliche Auffassung von Konfigurationen haben. Kannst du mal etwas konkreter Beschreiben was dein Ziel ist bzw. wie Deine Klasse(n) verwendet werden sollen?
phg 24.01.2013
0
Auch in PHP gibt es ebenfalls das static Schlüsselwort.
Bezugnehmend auf die Überschrift: Ich sehe hier keine Vererbung, das sind zwei unabhängige Klassen. Ausserdem denke ich nicht dass Du auf Protected Elemete von extern zugreifen kannst, müsste ich aber testen.
24.01.2013
Jaksa 4,0k 1 8
Sorry hatte das extends vergessen... jetzt stehts oben richtig.
spiike 24.01.2013
0
Zeit für einen Kaffee?
Wie Jaksa schon geschrieben hat: Variant erbt nicht von Main und weiß deshalb rein gar nichts von getOptions. Aber das ist nicht das einzige Problem: getOptions ist static und kann deshalb nicht auf $_data in Main zugreifen - es gibt da schlicht keine Instanz, auf die sich self beziehen könnte. Und vermutlich (ich bin in PHP nicht so fit) ist auch noch die Deklaration von $_data in Variant problematisch - wenn Du nämlich tatsächlich Variant von Main erben lassen solltest, stünde sie mit $_data in Main in Konflikt.
24.01.2013
Matthias Hlawatsch 13,2k 4 9
Das ist mir schon alles bewusst was ihr sagt, es geht auch nicht. self::$_data kann auch nicht aufgerufen werden, solange sie nicht static ist.

Mein Problem ist ja, das es aber trotzdem irgendwie gerne hinbekommen möchte mit der Vererbung den Aufruf so zu Starten das ich nur noch Variant::getOptions() tippen muss, ohne in jeder Klasse die Methoden neu zu schreiben.
spiike 24.01.2013
Gibt es irgendeinen Grund, warum Du nicht Main::getOptions() schreiben willst/kannst?
Matthias Hlawatsch 24.01.2013
Ja den gibts. Ich will doppelten Code vermeiden. Ich will ja auch die Methoden von Main per static zugreifen, aber die eigentlichen Daten erst in der Variant setzten.

Das Beispiel ist vlt. nicht gerade prädestiniert dafür. Es geht darum, dass ich nachher 30 Klassen habe die von der Main ableiten, in den 30 Klassen steht halt immer ein anderer Array inhalt... und da würde ich gern statisch drauf zu greifen...

aber ich glaube das geht so nicht....
spiike 24.01.2013
0
Mir fehlt noch ein wenig der Background, aber kannst Du Main und die Funktion getOptions nicht abstrakt machen und dann auf $data einfach verzichten?

<?php

abstract class Main
{

static abstract public function getOptions();
}

class Variant extends Main
{

static public function getOptions()
{
return array(
'key' => 'value',
'key2' => 'value2',
'key3' => 'value3',
);
}
}

$mike = Variant::getOptions();

var_dump($mike);
24.01.2013
Xantiva 2,3k 2 9
0
nur um die frage noch zu beantworten, man kann statische variablen überladen und auch drauf zugreifen. nicht ganz schön aber in deinem fall ist dein konstrukt eh unpassend.

...

protected static $_data;

static public function getOptions() {
$called = get_called_class();
return $called::$_data;
}
...
01.05.2014
di3 1

Stelle deine Php-Frage jetzt!