is it possible in magento php to invoke the method from parent class rather than from the overridden one,
I have extension overrides (A_CustomOptions_Model_Catalog_Product_Option extends Mage_Catalog_Model_Product_Option) and it overrides the construct method and I have got another extension wants to use the construct of parent class Mage_Catalog_Model_Product_Option
is there a way to do this???
more explanation:
class A_CustomOptions_Model_Catalog_Product_Option extends Mage_Catalog_Model_Product_Option {
protected function _construct() {
parent::_construct();
$this->_init('customoptions/product_option');
}
}
in another extension i'm getting collection for options
public function getOptions($srcId) {
$options = Mage::getModel('catalog/product_option')
->getCollection()
->addTitleToResult(Mage::app()->getStore()->getId())
->addPriceToResult(Mage::app()->getStore()->getId())
->addProductToFilter($srcId)
->addValuesToResult();
return $options;
}
however because this parent class Mage_Catalog_Model_Product_Option is overridden, it doesn't return me the parent options not overridden ones
Thanks
yes you can call parent constructor with use of below code
class A_CustomOptions_Model_Catalog_Product_Option extends Mage_Catalog_Model_Product_Option
{
public function __construct()
{
parent::__construct();
}
}
As your updated answer i think override class loaded at the last that might be not work.
hope this will sure work for you in simple OOP concept,
Related
Let's say I have a class
class Item {
public function __construct($id) {
if(!empty($id)) {
$this->doSomethingWithID($id);
}
}
public function dummyMethod() {
//does Something.
}
protected function doSomethingWithID($id) {
//Does something with the ID
}
}
If I have an inherited class like this:
class Product extends Item {
public function __construct() {
parent::__construct();
}
protected function doSomethingWithID($id) {
//OVERRIDES THE PARENT FUNCTION
}
}
Will the Product class use the overridden Method? or will it use the Parent method?
The more specific something is, the higher priority it gets in code.
Children with methods of the same name as their parents take priority. You CAN call a parents methods by saying super.method() though.
You have declared a new construct method in the inherited class so it will use that, but as the inherited class calls the parent class construct method it will use that.
If I have an abstract class like this:
abstract class MyApp
{
public function init()
{
$this->stuff = $this->getStuff();
}
public function getStuff()
{
return new BlueStuff();
}
}
And then I have a class that extends from this abstract class like this:
class MyExtendedClass extends MyApp
{
public function init()
{
parent::init();
}
public function getStuff()
{
return new RedStuff();
}
}
If I do:
$myobj = new MyExtendedClass();
$myobj->init();
Why does the method getStuff from the child class get called? Isn't $this in the context of the abstract class? If so, shouldn't the method of the abstract class get called?
Thanks!
New answer
In PHP you can use subclasses as if all methods in the parent class that don't exist in the subclass have been copied to the subclass. So your example would be the same as:
class MyExtendedClass extends MyApp {
public function init() {
$this->stuff = $this->getStuff();
}
public function getStuff() {
return new RedStuff();
}
}
Just think of the subclass as having all code of the parent class and you're normally all right. There is one exception to this rule: properties. A private property of a class can only be accessed by that class, subclasses can't access the private properties of parent classes. In order to do that you need to change the private property into a protected property.
Original answer
Abstract classes in PHP are just like regular classes with one big difference: they can't get initiated. This means you can't do new AbstractClass();.
Since they work exactly like regular classes for everything else, this also is the case for extending classes. This means that PHP first tries to find the method in the initiated class, and only looks in the abstract classes if it doesn't exist.
So in your example this would mean that the getStuff() method from MyExtendedClass is called. Furthermore, this means you can leave out the init() method in MyExtendedClass.
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!!
I'm having troubles finding a class name after extending other classes. Here are the relevant classes:
class Home extends Controller {
public function test() {
Example::all();
}
}
Class Example extends Active {
//Variables
}
Class Active extends Database {
public function all() {
//This is where I need to store a variable containing the class name Example.
}
}
I'm trying to retrieve the name of the Class Example in Class Active from when it is called from class Home, however I've found it impossible to do this so far without adding an extra argument (which I don't want to do).
You are looking for
get_called_class — the "Late Static Binding" class name
Example (demo)
class Home {
public function test() {
Example::all();
}
}
Class Example extends Active {
//Variables
}
Class Active {
public static function all() {
var_dump( get_called_class() );
}
}
Note that I have changed the signature of Active::all to static because calling non-static methods statically will raise E_STRICT warnings. In general, you want to avoid static methods and Late Static Binding.
have you tried with ReflectionObject class from PHP ? Have a look to this method
Hope this helps
My problem is in using Codeigniter custom library but I think it is not specific to that and more related to use of constructors in PHP.
I am trying to create a custom controller library in Codeigniter like this...
class MY_Controller extends Controller {
var $data = array();
function MY_Controller() {
parent::Controller();
$this->data['err'] = 'no';
$this->load->helper('utilities');
}
}
Now I create a codeigniter controller class like this...
class api_controller extends MY_Controller {
function get_data() {
$this->data['view'] = "data";
$this->load->view("data_view", $this->data);
}
function get_xml() {
$this->data['part'] = "xml";
$this->load->view("data_view", $this->data);
}
}
I want to ask that if the controller class extending the MY_Controller is instantiated when I access urls like api_controller/get_data and api_controller/get_xml, does the constructor of parent class always get called upon, i.e., MY_Controller() is always called.
Am I correct in inferring the following
get_data() called
-> $data => array ('err' => 'no', 'view' => 'data')
get_xml() called
-> $data => array ('err' => 'no', 'part' => 'xml')
Your code looks like it's using the PHP4 syntax for constructors. You should switch to the PHP5 syntax.
PHP4:
class MyClassName {
function MyClassName() {...} //constructor.
}
PHP5:
class MyClassName {
function __construct() {...} //constructor.
}
You can then call the constructor of a parent class by calling parent::__constructor(); from within the child class's __constructor() method:
class MyClassName extends SomeOtherClass {
function __construct() {
//...code here runs before the parent constructor.
parent::__construct();
//...code here runs after the parent constructor.
}
}
For PHP in general the parent constructor is not called default if the child has a constructor.
Constructors. It can be called using parent::_construct();
If you're using php 5+ you should go with the new recommended style of using function __construct() instead of the old style with a function named the same as a class.
As for CI-specific stuff I can't help you, sorry!
If you do not override __construct() in MY_Controller then Controller's __construct() will get run.
If you override it and then called parent::__construct() then it will run your own and the parent's.
So if you wanted it to run the parent's and your own you would do this
class MY_Controller extends Controller
{
var $data = array();
function __construct()
{
parent::__construct();
// Your code here
}
}
Yes, the parent constructor it is always called (you may want to rewrite them as __construct() however, thinking also at codeigniter 2.0 ).
If you really are in doubt toss in it an echo and see it for yourself.
Also the $this->data part is correct to me
You are right in your affirmations about the data array contents. In you code you wrote:
function MY_Controller() {
parent::Controller();
so the parents's class constructor is being called. There are lots of comments about PHP4 and PHP5 syntax, but basically everithing is ok.
In your question you wrote
that if the controller class extending the MY_Controller is instantiated
that is not correct. The instance is an object of class api_controller, calling the MY_Controller constructor is made using the same object. That is not the same, that is basic for polimorphism.
class Blog extends CI_Controller {
public function __construct()
{
parent::__construct();
// Your own constructor code
}
}