I would have thought lots of people would have wondered whether this is possible but I can't find any duplicate questions... do correct me.
I just want to know whether PHP offers pure virtual functions. I want the following
class Parent {
// no implementation given
public function foo() {
// nothing
}
}
class Child extends Parent {
public function foo() {
// implementation of foo goes here
}
}
Thanks very much.
You can create abstract functions, but you need to declare the parent class as abstract, too:
abstract class Parent {
// no implementation given
abstract public function foo();
}
class Child extends Parent {
public function foo() {
// implementation of foo goes here
}
}
Declare the method as abstract in the Parent class:
abstract public function foo();
There are abstract classes!
abstract class Parent {
// no implementation given
abstract public function foo();
}
}
class Child extends Parent {
public function foo() {
// implementation of foo goes here
}
}
Yes, that type of solution is possible, it's called polymorphism, you can do it without declaring an abstract class or an interface.
Related
I have a code like following ---
class CartItem{
var $v;
function __construct(){
$this->f();
}
function f(){
echo 'In parent';
}
}
class m extends CartItem{
function f(){
echo 'In child';
}
}
new m();
Now when creating instance of m()... it doesn't have any constructor, so it is calling parent classes constructor. Now inside that a function f is called.
What I want is -
if class m() have defined function f()... is should call it instead of parent class's function f().
But anyway it is calling parent classes function, as it was called from parent's constructor, irrespective of child class/ context :(
You want to call in __construct() a method that is not defined in the class. This is a sign that the CartItem class is an abstract concept and you don't intend to instantiate it (because an instance of CartItem probably doesn't contain enough information or behaviour for your project).
An abstract concept is implemented using an abstract class that defines as much as it can and defines abstract methods to be implemented in the concrete classes that extend it. The method f() is such a method that cannot be defined in the abstract concept and has to be defined in each class that extend it:
abstract class CartItem
{
public function __construct()
{
$this->f();
}
abstract protected function f();
}
class m extends CartItem
{
protected function f()
{
// Implement behaviour specific to this class
}
}
This is actually a really interesting question.
so, as I understand it, you're asking (if this isnt right please say):
can you call a function of a class that's extending a parent?
yes, you can... sort of, if the method in the child is static.
Take this example (Ive not used it in the constructor for simplicity of example, but it will work there too):
class ClassA {
public function testMeAsWell() {
return ClassB::testMe();
}
}
class ClassB extends ClassA {
static function testMe() {
return 'do something';
}
}
$child = new ClassB();
echo $child->testMe();
// outputs 'do something'
$parent = new ClassA();
echo $parent->testMeAsWell();
// also outputs 'do something'
the reason this works needs more research, but as a guess I would say that because PHP is compiled, it will know about both classes at run-time and therefore will be able to figure out what we wanted it to do.
So, further on, you want to use variables. Yes you can, but they would have to be static as well.
working example
What is the best of calling a method in child class. My IDE always shows Errors if i try to call the method directly.
class Base
{
public function DoIt()
{
$this->Generate(); //How to check if child implements Generate?
}
}
class Child extends Base
{
protected function Generate()
{
echo "Hi";
}
}
Simply put, you don't do this. It is very bad design: base classes should never assume anything about their descendants other than that they implement the contracts the base itself defines.
The closest acceptable alternative would be to declare abstract protected function Generate() on the parent so that it knows that all derived classes implement it. Of course this is not meant to be a mechanical solution: you should only do it if Generate is meaningful for all descendants of Base.
The issue is that your parent class doesn't define a Generate() method that a child class can override; you have to explicitly define this by creating an abstract method:
// class with at least one abstract method is
abstract class Base
{
public function DoIt()
{
$this->Generate();
}
// child classes MUST implement this method
abstract protected function Generate();
}
You can loosen the requirements by creating an empty implementation in the parent class:
class Base
{
public function DoIt()
{
$this->Generate();
}
// child classes MAY implement this method
protected function Generate() {}
}
As the title states, I'm trying to make a method in a parent class required. Although, I suppose it could be any class. For instance:
class Parent
{
function foo ()
{
// do stuff
}
}
class Child extends Parent
{
function bar ()
{
// do stuff after foo() has ran
}
}
Basically, I want foo() to be required to run or Child class doesn't run and returns an error or redirects to a different page. I could call the function, but I'm wondering If I can make it a requirement when extending the parent class.
If you leverage abstract classes and methods, you can force subclasses to implement the missing methods.
abstract class ParentClass
{
public function foo ()
{
// do stuff
$this->bar();
}
abstract protected function bar();
}
class Child extends ParentClass
{
protected function bar()
{
// does stuff
}
}
Subclasses that don't implement bar() will generate a fatal error.
What you should probably do is override Parent::foo() and then call the parent method in the overridden method like so:
class Parent
{
function foo ()
{
// do stuff
}
}
class Child extends Parent
{
function foo ()
{
if(!parent::foo()) {
throw new Exception('Foo failed');
}
// do child class stuff
}
}
Why not just set a boolean in function foo() that acts as a flag. Check to see if it has been set in the child class/functions, and you're all set.
Have the child call the function from the parent in the construct.
class Child extends Parent
{
function bar ()
{
// do stuff after foo() has ran
}
function __construct(){
parent::foo();
}
}
As already mentioned, it sounds like you want foo() to be abstract, forcing child classes to override it.
Any class containing an abstract class in PHP requires your parent class to be abstract too. This means it can't be instantiated (constructed), only derived / sub-classed. If you try to instantiate an abstract class the compiler will issue a fatal error.
http://php.net/manual/en/language.oop5.abstract.php
See the code in Peter Bailey's answer.
If you're not actually initializing any code within parent class you should use an object interface. Interface methods have to be implemented or the script will throw a fetal error.
More information on them can be found: http://us3.php.net/interface.
I think this might be the only way of implementing such functionality, as I don't think there is a built in solution.
class Parent
{
public $foo_accessed = FALSE;
function foo ()
{
$this->foo_accessed=TRUE;
// do stuff
}
}
class Child extends Parent
{
function bar ()
{
if($this->foo_accessed==TRUE) {
// do stuff after foo() has ran
} else {
// throw an error
}
}
}
Do not depend on other methods. Make sure they've ran.
class Parent
{
function foo()
{
// do stuff
}
}
class Child extends Parent
{
private function bar()
{
// do child class stuff
}
public function doFooBar()
{
parent::foo();
$this->bar();
}
}
Following approach will only ever complain after all processing has been done - however if that is fair to you it will definately make sure foo() has been called in the parent class or otherwise trigger a condition that you can act upon.
class DemandingParent {
private $hasFooBeenCalled = false;
public function foo() {
$this->hasFooBeenCalled = true;
/* do Stuff */
}
public function __destruct() {
if (!$this->hasFooBeenCalled) {
throw new Exception("Naughty Child! Call your parent's foo b4 you speak up!");
}
}
}
In the project my team is currently working on, we're modifying a commercial PHP application. The app is strewn with code where a parent class checks for and works with a property that doesn't exist in the parent class, like so:
class A
{
function doSomething()
{
if (property_exists($this, 'some_property'))
{
$this->some_property = $_REQUEST['val'];
}
}
}
class B extends A
{
protected $some_property;
function doSomething()
{
parent::doSomething();
}
}
We feel vaguely dirty having to modify this code; is this proper design? What are the ways (other than the obvious) something like this can be avoided?
You might consider abstracting the parent class. So the methods that the children must have are declared in the parent, but not implemented.
Relying upon methods that must exist in a subclass is not dirty, as long as you can declare them as abstract.
However, it is not good practice to rely on and manipulate properties outside of a class. It's best to use abstract setters, like this:
abstract class A
{
abstract protected function setSomeProperty($data);
public function doSomething()
{
$this->setSomeProperty($_REQUEST['val']);
}
}
class B extends A
{
private $some_property;
public function doSomething()
{
parent::doSomething();
}
protected function setSomeProperty($data)
{
$this->some_property = $data;
}
}
More info here: PHP Class Abstraction
However, since you said you're not allowed to modify the parent class, I would suggest making a subclass that acts as an Adapter to what the parent class "expects", and a class that you're able to design "properly".
You can create a virtual method hook in the parent class which can later be overridden by children.
I think it's more neat to create a sub-class, where all members have function doSomething(). In that case you don't create a not-working function in a parent class (with eventual hacks), but still have the general "super-function".
class A
{
}
class C extends A {
protected $some_property;
function doSomething()
{
$this->some_property = $_REQUEST['val'];
}
}
class B extends C
{
protected $some_property;
function doSomething()
{
parent::doSomething();
}
}
I have a classB which extends classA.
In both classA and classB I define the method fooBar().
In fooBar() of classB I want to call fooBar() of classA at the beginning.
Just the way I'm used to, from Objective-C. Is that possible in PHP? And if so, how?
parent::fooBar();
Straight from the manual:
The ... double colon, is a token that allows access to ... overridden properties or methods of a class.
...
Example #3 Calling a parent's method
<?php
class MyClass
{
protected function myFunc() {
echo "MyClass::myFunc()\n";
}
}
class OtherClass extends MyClass
{
// Override parent's definition
public function myFunc()
{
// But still call the parent function
parent::myFunc();
echo "OtherClass::myFunc()\n";
}
}
$class = new OtherClass();
$class->myFunc();
?>
Just a quick note because this doesn't come up as easy on Google searches, and this is well documented in php docs if you can find it. If you have a subclass that needs to call the superclass's constructor, you can call it with:
parent::__construct(); // since PHP5
An example would be if the super class has some arguments in it's constructor and it's implementing classes needs to call that:
class Foo {
public function __construct($lol, $cat) {
// Do stuff specific for Foo
}
}
class Bar extends Foo {
public function __construct()(
parent::__construct("lol", "cat");
// Do stuff specific for Bar
}
}
You can find a more motivating example here.