Parent variabele in child class

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Sander Z

Sander Z

02/12/2015 15:20:03
Quote Anchor link
Gezocht op Google maar niet gevonden.
Ik wil in mijn child class de waarde welke in de parent staat opvragen.
Als ik onderstaande doe dan krijg ik na $b->getVal() als waarde a terug. Hier verwachtte ik c.

Ik begin me nu te te verdiepen in OOP en ben wat dingen aan het uitproberen. Al doende leert men.
Ik weet dat dit waarschijnlijk basis materiaal is maar hier loop ik tegenaan.
Wat moet ik doen om na $b->getVal() als resultaat c te krijgen?


Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
class A {
   protected $_value;

   private function __construct() {
      $this->_value = 'a';
   }

   public function setValue($val) {
      $this->_value = $val;
   }

   protected function getValue($val) {
      return $this->_value;
   }
}

class B extends A {

   private function __contruct() {
      parent::__construct();
   }

   public function getVal() {
      return parent::getValue();
   }
}

$a = new A;
$b = new B;
$a->setValue('c');
echo $b->getVal();
Gewijzigd op 02/12/2015 15:23:07 door Sander Z
 
PHP hulp

PHP hulp

27/04/2024 05:16:06
 
Ward van der Put
Moderator

Ward van der Put

02/12/2015 15:30:11
Quote Anchor link
Er is een verschil tussen klassen en objecten van die klassen. Je hebt nu twee verschillende objecten, $a en $b, maar class B extends A betekent niet dat object $b van klasse B daarmee automatisch wordt afgeleid van object $a van klasse A. Objecten zijn geen afgeleiden van objecten, maar van klassen. Er is geen enkel direct verband tussen $a en $b, dus een waarde van een eigenschap van object $a wijzigen leidt niet automatisch tot een wijziging van die eigenschap van object $b.

Edit. Verder moet een constructor van een klasse overigens public zijn, anders kan er geen object worden geconstrueerd.
Gewijzigd op 02/12/2015 15:32:36 door Ward van der Put
 
Sander Z

Sander Z

02/12/2015 15:53:12
Quote Anchor link
Thanks!
Ik zit nu in de auto en zat het nog te overdenken. Ik kwam al tot dezelfde conclusie. Ik denk ondertussen ook te weten hoe het wel te bereiken wat ik wil. Ik ga straks thuis weer even experimenteren.
Bedankt in ieder geval.
 
Ward van der Put
Moderator

Ward van der Put

02/12/2015 16:25:32
Quote Anchor link
Je kunt het ook nog zó zien: object $b is afgeleid van class B is afgeleid van class A.
Nergens komt daarin object $a voor.

>> Ik denk ondertussen ook te weten hoe het wel te bereiken wat ik wil.

Misschien kun je dat straks nog even posten? Er zijn namelijk voor de meeste OOP-dingen design patterns bedacht en waarschijnlijk zijn er wel een of twee te noemen waarmee je dat doel kunt bereiken.
 
Sander Z

Sander Z

02/12/2015 16:47:41
Quote Anchor link
Doe ik

Toevoeging op 02/12/2015 17:33:41:

Dit is hoe ik uiteindelijk bereikte wat ik wilde:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
class A {
   protected $_value;

   public function __construct() {
      $this->_value = 'a';
   }

   public function setValue($val) {
      $this->_value = $val;
   }

}

class B extends A {

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

   public function getVal() {
      return $this->_value;
   }
}

$b = new B;
$b->setValue('c');
echo $b->getVal();  // c
Gewijzigd op 02/12/2015 17:34:22 door Sander Z
 
Ward van der Put
Moderator

Ward van der Put

02/12/2015 18:01:19
Quote Anchor link
Dat kan korter en krachtiger:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
class A
{
    protected $_value = 'a';

    public function setValue($val)
    {

        $this->_value = $val;
    }
}


class B extends A
{
    public function getValue()
    {

        return $this->_value;
    }
}


$b = new B;
echo $b->getValue();  // a
?>

Twee verschillen:

• Als je de constructor van class B weglaat, wordt automatisch de constructor van class A gebruikt.

• Aangezien je in de constructor van class A alleen een eigenschap instelt, kun je die eigenschap ook rechtstreeks definiëren en de constructor van class A weglaten.
 
Thomas van den Heuvel

Thomas van den Heuvel

02/12/2015 19:42:35
Quote Anchor link
Ward van der Put op 02/12/2015 15:30:11:
Edit. Verder moet een constructor van een klasse overigens public zijn, anders kan er geen object worden geconstrueerd.

Wordt hier niet juist gebruik van gemaakt (een niet-publieke __construct methode) bij de implementatie van bepaalde design patterns om af te dwingen dat er geen objecten geïnstantieerd kunnen worden (althans niet via de standaard weg)? Zoals een Factory?

Ik kan mij vergissen, design patterns zijn niet mijn sterkste punt maar ik heb weleens implementaties van *iets* gezien waarbij bewust geen publiek toegankelijke constructor werd gebruikt.

/offtopic
 
Ward van der Put
Moderator

Ward van der Put

03/12/2015 12:50:35
Quote Anchor link
Thomas van den Heuvel op 02/12/2015 19:42:35:
Ik kan mij vergissen, design patterns zijn niet mijn sterkste punt maar ik heb weleens implementaties van *iets* gezien waarbij bewust geen publiek toegankelijke constructor werd gebruikt.

Klopt, dan heb je het bijvoorbeeld over het service Locator pattern aka registry pattern, dat bij PHP vaak een singleton pattern interface implementeert:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
interface SingletonInterface
{
    public static function getInstance();
}

?>

Net zoals bij de centrale registry van een besturingssysteem is er maar één service locator c.q. registry, zodat services kunnen worden gedeeld door klassen, subsystemen, applicaties, enzovoort. Daarom wordt het gebruik van de constructor en de magische methode __clone() verboden:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
45
46
47
48
49
50
51
52
53
<?php
class Registry implements SingletonInterface
{
    /**
     * @var array $Data
     * @var object|null $Instance
     */

    private $Data = array();
    private static $Instance = null;

    // Disable object instantiation and cloning
    private function __construct() {}
    private function __clone() {}

    /**
     * Get the single instance of the registry.
     *
     * @param void
     * @return self
     */

    public static function getInstance()
    {

        if (self::$Instance === null) {
            self::$Instance = new Registry();
        }


        return self::$Instance;
    }


    /**
     * Set a shared value in the global registry.
     *
     * @param string $key
     * @param mixed $value
     * @return void
     */

    public function set($key, $value)
    {

        $this->Data[$key] = $value;
    }


    /**
     * Get a value from the registry.
     *
     * @param string $key
     * @return mixed|null
     */

    public function get($key)
    {

        return (isset($this->Data[$key]) ? $this->Data[$key] : null);
    }
}

?>

Dit design pattern garandeert dat er maar één instantie van de registry in omloop is:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
// Fatal error: Call to private Registry::__construct()
$registry = new Registry();

// Het moet zo:
$registry = Registry::getInstance();
?>

Volgens sommigen zijn dit anti-patterns, onder andere omdat je een tightly-coupled systeem krijgt waarin (te) veel afhankelijk is gemaakt van één God particle. Praktisch bezwaar is daarnaast dat je unit tests niet zuiver kunt houden.
 
Sander Z

Sander Z

03/12/2015 15:10:12
Quote Anchor link
@Ward:
Bedankt voor de moeite om me nog wat extra's mee te geven!
Wordt gewaardeerd!

Ward van der Put op 02/12/2015 18:01:19:
• Als je de constructor van class B weglaat, wordt automatisch de constructor van class A gebruikt.


Ok duidelijk. Maar als ik in class B toch wel iets via zijn constructor zou willen doen dan is dit wel nodig?:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
parent::__construct();


Of is dat sowieso niet nodig?
Gewijzigd op 03/12/2015 15:10:57 door Sander Z
 
Ward van der Put
Moderator

Ward van der Put

03/12/2015 15:18:09
Quote Anchor link
Ja, dan moet je inderdaad in class B de constructor van class A actief aanroepen.
Er zijn namelijk ook situaties denkbaar waar de constructor geheel iets anders doet, dus de constructor van class B die van class A geheel vervangt of "overschrijft". Dat geldt ook voor andere methoden die een child class erft van de parent.

Verder biedt het je dan de mogelijkheid om de volgorde van de operaties zelf te bepalen: direct de constructor van A aanroepen en dan die van B iets extra's laten doen of omgekeerd juist eerst in de constructor van B iets extra's doen en daarna pas de constructor van de parent aanroepen.
 
Sander Z

Sander Z

04/12/2015 22:05:58
Quote Anchor link
Interessant. Ik ga daar eens mee spelen om te kijken wat de mogelijkheden zijn.
Wederom thanks!
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.