I am trying to implement a code somewhat like below but not able to understand one issue, as per my understanding it should have printed the data like this:
Foo::testPrivate
Foo::testPublic
But its displaying output as ::
Bar::testPrivate
Foo::testPublic
The code is::
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new Foo();
$myFoo->test();
Can somebody please explain this?
As per my Understanding
Displaying output is right because of you are created object of "Foo" class and then after call test() function is inside the "Bar" class
In test() function of Bar class is call testPrivate() using "this" keyword so call the function in same class and testPrivate() is also private so that's why display result like :
Bar::testPrivate
Foo::testPublic
Make changes to private function testPrivate() { } to public function testPrivate() in both the class for displayed your accepted result
Result after made this changes is :
Foo::testPrivate
Foo::testPublic
Related
I have problem, can i call constructor without create 'new class()' ? Or you maybe have another way for this :
<?php
class a
{
public static $hello;
public function say()
{
return self::$hello;
}
}
class b extends a
{
public function __construct()
{
self::$hello = 'hello world';
}
}
echo b::say();
?>
I have try with :
$b = new b();
echo $b->say();
And it's work. But i want to use b::say();
Can help me?
Thank you!!
Check out this. Is this good for you?
<?php
class a {
public static $hello;
public static function say() {
return self::$hello;
}
}
class b extends a {
public function __construct() {
self::$hello = 'hello world';
}
public static function factory() {
return new b();
}
}
echo b::factory()->say();
?>
Actually I couldn't find a way to do this without calling constructor. This is how the workaround looks like. factory is just a name. you can rename it.
calling class method (with constructors) without object instantiation in php
You have asked: "can i call constructor without create 'new class()' ?"The answer: No.
... Classes which have a constructor method call this method on each
newly-created object
You have requested "But i want to use b::say();"
b::say(); - is call of static method.You can't override non-static parent method to static. But you can restructure your base class class a to make say() method static.
<?php
class a
{
public static $hello;
public static function say()
{
return self::$hello;
}
}
class b extends a
{
public function __construct()
{
self::$hello = 'hello world';
}
}
The thing that you were missing was you needed to add your content to your new class method. - Just call it like so:
$b = new b('Some words');
echo $b->say();
When calling a new class and using a constructor - You will want to add the content in the paramaters for the new class you are making.
It acts as if you are calling the __construct function. - Calling new class($a) will call the __construct($a) function once making the object.
Hope that this helped a bit :)
Yes it is possible just make the say() function static like this :
public static function say()
{
return self::$hello;
}
Declaring class methods as static makes them accessible without needing an instantiation of the class.
This example looks to me like late static binding. So try changing that return self::$hello; into return static::$hello;
I am new to php and I was going through the documentation for the visibility. I am little confused with this example in the documentation.
when the call to $myFoo->test() is made, shouldn't it make a call to Foos $this->testPrivate(); . I mean shouldn't $this be Foos Object rather than Bar object? . As per my knowledge(I might be wrong here) Foo will have kind of its own test() method which is inherited from Bar and calling $myFoo->test() will make a call to '$this->testPrivate' where the $this should be Foos object myFoo. so How is it calling Bar's testPrivate method?
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>
test() is in Bar, and will call the highest-level methods that Bar has access to. It has access to Foo's testPublic (because it is public) so it can call that, but it doesn't have access to Foo's testPrivate() (because it's private to Foo) so it calls it's own testPrivate() instead
i am working on PHP inheritance(just started leraning PHP). I found that base class methods does not display the value of properties when accessed with a child class object. My code look like this.
<?php
class Base
{
public $pr1;
public $pr2;
function __construct()
{
print "In Base class<br>";
}
public function setPropertie($pr1,$pr2)
{
$this->$pr1=$pr1;
$this->$pr2=$pr2;
}
public function display(){
echo "propertie1".$this->pr1."<br>";
echo "propertie2".$this->pr2."<br>";
}
function __destruct()
{
print "Destroying Baseclass<br>";
}
}
class Child extends Base
{
function __construct()
{
parent::__construct();
print "In Subclass<br>";
}
function __destruct()
{
print "Destroying Subclass<br>";
}
}
$obj=new Child();
$obj->setPropertie('Abhijith',22);
$obj->display();
?>
I can't find what is the problem in the code. How to fix this problem?
You are accessing property incorrectly inside the setPropertie() method. Remove $ from both $pr1 and $pr2 property to access them
Wrong way
$this->$pr1=$pr1;
$this->$pr2=$pr2;
Correct way
$this->pr1=$pr1;
$this->pr2=$pr2;
In the documentation is this example and understand it without problems
class Bar{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test();
The result is:
Bar::testPrivate
Foo::testPublic
But now redefine the test () method in the class foo
class Bar{
public function test() {
echo '<br>Im Bar::test';
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "<br>Bar::testPublic\n";
}
private function testPrivate() {
echo "<br>Bar::testPrivate\n";
}
}
class Foo extends Bar{
public function test() {
echo '<br>Im Foo::test';
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "<br>Foo::testPublic\n";
}
private function testPrivate() {
echo "<br>Foo::testPrivate\n";
}
}
$myFoo = new Foo();
$myFoo->test();
The result is:
Im Foo::test
Foo::testPrivate
Foo::testPublic
php allows me to override the private method testPrivate (), Why?
Why not? It's difficult to answer that question as it's just how PHP works. If you want to prohibit your methods from being overwritten then you can use the final keyword.
Additionally, in your example, if you do not declare the private method within Foo, you will get an error as Foo technically has no definition for that method. Extending classes have no visibility of any private properties or methods within their parent class.
I didn't get why the first output of the code prints "Bar::testPrivate" as we are calling the test method of the parent class using sub class's instance.So, when calling the first line of code inside the test function which is "$this->testPrivate();" should call testPrivate method of the sub class hence printing "Foo::testPrivate" and not "Bar::testPrivate".
<pre>
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
</pre>
Your class Foo doesn't have a test() method. You can call $myFoo->test() because the method test() is inherited from class Bar. You'll have to override the method test() within class Foo just as you did with methods testPrivate() and testPublic().
You are correct that it is calling the method of the base class, but in this case Bar is your base class. Check out the example here.
If you are looking to inherit all the functions from your base (parent) class then you should explicitly call it's constructor in the child class. Otherwise you will need to override those methods. Also, when using the actual instance (i.e. you created an object) functions declared private are only available to that class. Use protected for classes that will inherit that function. e.g.:
class Foo {
public function __construct() {
echo "Foo constructed...\n";
$this->fooOnly();
}
private function fooOnly() {
echo "Called 'fooOnly()'\n"; //Only available to class Foo
}
protected function useThisFoo() {
echo "Called 'useThisFoo()'\n"; //Available to Foo and anything that extends it.
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct(); //Now Bar has everything from Foo
}
public function testFooBar() {
//$this->fooOnly(); //Fail - private function
$this->useThisFoo(); //Will work - protected function is available to Foo and Bar
}
}
$bar = new Bar();
$bar->testFooBar(); //Works - public function will internally call protected function.
//$bar->fooOnly(); //Fail - private function can't be accessed in global space
//$bar->useThisFoo(); //Fail again - protected function can't be access in global space