php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #37320 Inheritance Problem: Private members can't be overridden by child classes
Submitted: 2006-05-05 03:59 UTC Modified: 2006-05-30 21:28 UTC
Votes:3
Avg. Score:4.0 ± 0.8
Reproduced:3 of 3 (100.0%)
Same Version:2 (66.7%)
Same OS:1 (33.3%)
From: php at dayclan dot org Assigned: helly (profile)
Status: Not a bug Package: Class/Object related
PHP Version: 5.* OS: *
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: php at dayclan dot org
New email:
PHP Version: OS:

 

 [2006-05-05 03:59 UTC] php at dayclan dot org
Description:
------------
If a parent and child class both define the same member variable, and if the visibility of the member variable in the parent is "private", all references in the parent class will access that private variable.  If the parent variable is protected or public, though, all references in the parent class will access the child's variable.

The reason I suspect this is a bug and not designed behavior is because the same is not true for member functions.  If a parent class has a private member function and the child class defines the same member function with protected visibility, all references to the function in the parent class will go to the child class.

It's also annoying if you're using a child class to override a subset of the functionality in a parent class. 

Reproduce code:
---------------
class Class1
{   
   private $var1 = 'Class1 var1';
   protected $var2 = 'Class1 var2';
   
   public function printOut() {
      echo $this->var1 . "\n";
      echo $this->var2 . "\n";
      echo $this->func1();
   }

   private function func1() {
      echo 'Class1 func1';
   }
}

class Class2 extends Class1
{
   protected $var1 = 'Class2 var1';
   protected $var2 = 'Class2 var2';

   protected function func1() {
      echo 'Class2 func1';
   }
}

$class2 = new Class2();
$class2->printOut();

Expected result:
----------------
Class2 var1
Class2 var2
Class2 func1

Actual result:
--------------
Class1 var1
Class2 var2
Class2 func1

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-05-27 01:10 UTC] helly@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

your printout function is defined in  Class1 thuse the printout is done with Class1 context in which Class1::var1 is valid and Class2::var1 cannot be seen.

Hint use var_dump() instead of your printout function:

marcus@zaphod /usr/src/php-cvs $ php ~/tmp/bug37320.php
make: `sapi/cli/php' is up to date.
object(Class2)#1 (3) {
  ["var1":protected]=>
  string(11) "Class2 var1"
  ["var2":protected]=>
  string(11) "Class2 var2"
  ["var1":"Class1":private]=>
  string(11) "Class1 var1"
}
marcus@zaphod /usr/src/php-cvs $ ../PHP_5_2/sapi/cli/php ~/tmp/bug37320.php
object(Class2)#1 (3) {
  ["var1:protected"]=>
  string(11) "Class2 var1"
  ["var2:protected"]=>
  string(11) "Class2 var2"
  ["var1:private"]=>
  string(11) "Class1 var1"
}
marcus@zaphod /usr/src/php-cvs $ ../PHP_5_1/sapi/cli/php ~/tmp/bug37320.php
object(Class2)#1 (3) {
  ["var1:protected"]=>
  string(11) "Class2 var1"
  ["var2:protected"]=>
  string(11) "Class2 var2"
  ["var1:private"]=>
  string(11) "Class1 var1"
}
 [2006-05-30 21:28 UTC] php at dayclan dot org
Thank you for responding.

I hope you won't mind answering a few more questions for me.

Why do functions work differently than variables?  Why when I'm in Class1 context and I call $this->func1() does Class2::func1 get called?

You say "the printout is done with Class1 context in which Class1::var1 is valid and Class2::var1 cannot be seen".  If Class2:var2 can be seen when in Class1 context, why can't Class2:var1 be seen?  What's the difference?  If it "can't be seen", why does var_dump see it?

Why when you call var_dump($class2) do 2 separate definitions for var1 show up?  
  
  ["var1:protected"]=>
  string(11) "Class2 var1"
  
  AND

  ["var1:private"]=>
  string(11) "Class1 var1"
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sat Sep 19 20:01:33 2020 UTC