inheriting properties in php - php

I have a superclass which contains properties & methods for setting them
class Super{
private $property;
function __construct($set){
$this->property = $set;
}
}
then I have a subclass that needs to use that property
class Sub extends Super{
private $sub_property
function __construct(){
parent::__construct();
$this->sub_property = $this->property;
}
}
but I keep getting an error
Notice: Undefined property: Sub::$property in sub.php on line 7
where am I going wrong?

The error is saying that it's trying to find a local variable called $property which doesn't exist.
To refer to $property in object context, as you intended, you need $this and the arrow.
$this->sub_property = $this->property;
secondly, the line above will fail as is because $property is private to the Super class. Make it protected instead, so it's inherited.
protected $property;
Third, (thanks Merijn, I missed this), Sub needs to extend Super.
class Sub extends Super

You need to make your $sub_property protected instead of private.

You'll also need to specify that the subclass extends from the superclass:
class Sub extends Super {
// code
}

Related

Private property accessibility confusion

I am now really confused about the following:
class A {
public function setPropertyValue($prop, $val) {
$this->$prop = $val;
}
}
class B extends A {
private $foo;
}
$obj = new B();
$obj->setPropertyValue("foo", "whatever"); // Fatal error: Uncaught Error: Cannot access private property B::$foo
Why and what is the point of not being able to access the private property since it is a property of B object that was instantiated and that the method is called on?
The error would make sense if it were the other way around: $foo being a private property of A and therefore not visible through inheritance to B.
I just cannot figure out why would this behavior be useful.
Private is only for the class instance using it. If you want to make it available for child or parent classes, but keep it unavailabe for public, make it protected.
class A
{
public function setPropertyValue($prop, $val)
{
$this->$prop = $val;
}
}
class B extends A
{
protected $foo;
}
$obj = new B();
$obj->setPropertyValue("foo", "whatever");
Per OOP principles:
The visibility of a property, a method or a constant can be defined by prefixing the declaration with the keywords public, protected or private.
Class members declared public can be accessed everywhere.
Members declared protected can be accessed only within the class itself and by inheriting and parent classes.
Members declared as private may only be accessed by the class that defines the member.
private - the property or method can ONLY be accessed within the class
You can't access or set a private property from anywhere else except the class it is created.
The only way of working with a private property in a class is by modyfying it in a public method of the same class.

Trying to understand PHP OOP

I'm wondering why the following code won't print out anything. I'm trying to access Bar::$some_var from method in parent class. Where Bar::$some_var is defined in it's constructor.
I've tried using self::$some_var and static::$some_var in Foo::hello() but neither worked. Do I have to make $some_var static?
class Foo {
private $some_var;
public function __construct() {
$this->some_var = 5;
}
public function hello() {
print $this->some_var;
}
}
class Bar extends Foo {
public function __construct() {
$this->some_var = 10;
}
}
$bar = new Bar();
$bar->hello();
Thanks in advance.
private makes a member variable unavailable outside of a class. You need to use protected to allow extending classes to have access to that variable.
protected $some_var;
See Visibility
Your class variable cannot be private if you would like your child class to access it.
Try protected instead and it should work!
:: operator is used to access class items (constants, static
variables, static methods)
-> operator is used to access object items (non static properties and methods)
anyway in your code the problem is visibility of $some_var. It has to be almost protected, public will also work

PHP change method/function visibility

I am trying to write a PHP class in which I change the visibility of a few methods from protected to public. I believe I remember you can do this in C++, but I did a few searches and I am not coming up with anything for that in PHP. Does anyone know if this is even possible in PHP?
For example, suppose this class:
class ABC {
protected function foo() {
// Do something
}
}
class DEG extends ABC {
// can I make foo public now?
}
You can change the visibility of members when deriving from a base class like this:
class Base
{
protected function foo() {}
}
class Derived extends Base
{
public function foo() { return parent::foo(); }
}
You can also do the same with properties (redefine a protected property as public).
However, be aware that if the base property is private then you will not actually increase its accessibility but rather declare a new property with the same name. This is not an issue with functions, as if you tried to call a private base method you would immediately get a runtime error.
You can overwrite a method in a derived class to highten it´s visibility (e.g. protected->public). Make the new function return it´s parent.
You cannot do so to limit it´s visibility (e.g. public->protected), but you can implement a method that checks the backtrace for the caller and thwors an exception if it´s a foreign class.
You can always use the reflection API to do all kinds of changes to the visibility.
Yes, it can be done. Quoting from PHP manual..
The visibility of a property or method can be defined by prefixing the
declaration with the keywords public, protected or private. Class
members declared public can be accessed everywhere. Members declared
protected can be accessed only within the class itself and by
inherited and parent classes. Members declared as private may only be
accessed by the class that defines the member.
And the example from there as well..
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private
Edit : Yes, you can change visibility of public and protected members. Another example from PHP manual..
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// We can redeclare the public and protected method, but not private
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // Works
echo $obj2->private; // Undefined
echo $obj2->protected; // Fatal Error
$obj2->printHello(); // Shows Public, Protected2, Undefined
?>

Calling a child method from the parent class in PHP

Having the following class hierarchy:
class TheParent{
public function parse(){
$this->validate();
}
}
class TheChild extends TheParent{
private function validate(){
echo 'Valid!!';
}
}
$child= new TheChild();
$child->parse();
What is the sequence of steps in which this is going to work?
The problem is when I ran that code it gave the following error:
Fatal error: Call to private method TheChild::validate() from context 'TheParent' on line 4
Since TheChild inherits from TheParent shouldn't $this called in parse() be referring to the instance of $child, so validate() will be visible to parse()?
Note:
After doing some research I found that the solution to this problem would either make the validate() function protected according to this comment in the PHP manual, although I don't fully understand why it is working in this case.
The second solution is to create an abstract protected method validate() in the parent and override it in the child (which will be redundant) to the first solution as protected methods of a child can be accessed from the parent?!!
Can someone please explain how the inheritance works in this case?
Other posters already pointed out that the mehods need to be protected in order to access them.
I think you should change one more thing in your code. Your base class parent relies on a method that is defined in a child class. That is bad programming. Change your code like this:
abstract class TheParent{
public function parse(){
$this->validate();
}
abstract function validate();
}
class TheChild extends TheParent{
protected function validate(){
echo 'Valid!!';
}
}
$child= new TheChild();
$child->parse();
creating an abstract function ensures that the child class will definitely have the function validate because all abstract functions of an abstract class must be implemented for inheriting from such a class
Your idea of inheritence is correct, just not the visibility.
Protected can be used by the class and inherited and parent classes, private can only be used in the actual class it was defined.
Private can only be accessed by the class which defines, neither parent nor children classes.
Use protected instead:
class TheParent{
public function parse(){
$this->validate();
}
}
class TheChild extends TheParent{
protected function validate(){
echo 'Valid!!';
}
}
$child= new TheChild();
$child->parse();
FROM PHP DOC
Visibility from other objects
Objects of the same type will have access to each others private and protected members even though they are not the same instances. This is because the implementation specific details are already known when inside those objects.
Private can only be accessed by the class which defines or Same object type Example
class TheChild {
public function parse(TheChild $new) {
$this->validate();
$new->validate(); // <------------ Calling Private Method of $new
}
private function validate() {
echo 'Valid!!';
}
}
$child = new TheChild();
$child->parse(new TheChild());
Output
Valid!!Valid!!

How can a PHP class that extends another inherit a private function?

I am trying to extend a PHP class without rewriting the whole thing. Here is an example:
<?
$a = new foo();
print $a->xxx();
$b = new bar();
print $b->xxx();
class foo {
const something = 10;
public function xxx() {
$this->setSomething();
return $this->something;
}
private function setSomething() {
$this->something = self::something;
}
}
class bar extends foo {
public function xxx() {
$this->setSomething();
$this->something++;
return $this->something;
}
}
?>
However when I run the script I get the following error:
Fatal error: Call to private method foo::setSomething() from context 'bar' in test.php on line 23
It would seem that bar is not inheriting the private function setSomething(). How would I fix this without modifying the foo class?
No, you can not fix this without modifying the foo class. Because an inherited class can not access parent class's private members. It's a very basic oop rule.
Declare setSomething() as protected. It'll be solved.
See manual
Private members are not inheritable, you can not use them in sub class. They are not accessible outside the class.
You must need to make that function as protected or public. Protected members are accessible to that class and for the inherited class. So, your best bet is to make that function Protected.
bar is inheriting the function alright, but it can't call it. That's the whole point of private methods, only the declaring class can call them.
Try reflection
http://php.net/manual/en/class.reflectionclass.php
Also:
Call private methods and private properties from outside a class in PHP
Did you try this?
class bar extends foo {
public function xxx() {
$this->something = parent::xxx();
$this->something++;
return $this->something;
}
}
Note the parent::xxx(); is public, so it should work... even though it looks like a static call.
Without modifying the original class, there is no way for the inherited class to directly call private methods of the parent class.

Categories