Jump to content

Inheritance, and accessing parent methods


mikesta707

Recommended Posts

Ok, I have a parent class that looks like this

abstract class MasterConverter {
private $file, $system, $uifile, $format;

abstract public function execute();
abstract protected function createCommand(); //Changing stuff.
abstract protected function setFile($file);
abstract protected function setFormat($format);

protected function setuiFile($uifile) {
	$this->uifile = $uifile;
}	
}

 

And I access this function in a child class like so

public function setFile($file) {
	//echo $file."<br />";
	$ext = end(explode('.', $file));
	//echo $ext."<br />";
	if (!in_array($ext, $this->allowedFiles)){
		echo "Invalid file type!";
		exit();
	}
	$this->file = $file;
	$newFile = sha1(substr($file, 0, strrpos($file, '.')));
	$this->setuiFile($newFile);//seems to be a problem with this
}

 

that call doesn't seem to be working. Is there a special way I have to call this function

//i tried
parent::setuiFile()
ClassName::setuiFile()

 

any ideas? I'm sure i just have the wrong syntax

Link to comment
Share on other sites

I didn't see anything wrong with that. So I created a quick example, and as I thought it works fine. So there must be a problem somewhere else..

 

ex:

 

abstract class ParentClass
{
protected function someMethod()
{
	echo 'Works';
}
}

class childClass extends ParentClass
{
public function callParentMethod()
{
	$this->someMethod();
}
}

$cl = new childClass();
$cl->callParentMethod();

 

Works.

Link to comment
Share on other sites

Are you calling the parent method inside child classes own method like in the example provided by AlexWD or are you declaring the same abstract function as the parent abstract defines? If the latter the reason why you cant call that way lies in the word protected. Protected means that you can use the protected methods only in the parent class and in classes that are inheritated from the parent. Meaning that you can't use that method call outside these classes. Except calling it via some child classes method. Change it to public if you want to call the method directly from your code outside the classes.

Link to comment
Share on other sites

In my code it shows me calling it in the child method, I do know what protected means, and I intended for that method to be protected. Besides, if I was calling it outside the class definition, I would be getting an error message.

 

I have figured out though that the method was indeed being called, but it lies in a different problem. For some reason, the the line

 

$this->uifile = $uifile;

 

isn't working. I know this because I have an if statement like the following

if (!isset($this->uifile)){
}

 

this gets called because for some reason $this->uifile isn't set. One thing I noticed, both setuifile and this-> uifile are parent methods and attributes respectively. I access the parent methods other attributes successfully,  but using a child method, not a parent method.

 

for example, i do this

function setFile($file){
$this->file = $file;
}

 

and this works. I am not sure whats going wrong here

Link to comment
Share on other sites

I tried that, and I got the same problem. that was my first reaction actually. The thing is that the other private variables ($file, $system, etc) are all set perfectly fine. Perhaps I will try setting just uifile to protected and see what happens. Thanks for the advice

Link to comment
Share on other sites

I'm pretty sure the other data members aren't being set properly.  Look at this test code:

 

   abstract class TestParent
   {
      private $first = "hi";
      private $second = "hello";
      private $third = "hola";
      private $fourth = "bonjour";

      protected function setFirst($first)
      {
         $this->first = $first;
      }
   }

   class TestChild extends TestParent
   {
      public function testData()
      {
         $this->setFirst("yo, wassup");

         echo "{$this->first}, {$this->second}, {$this->third}, and {$this->fourth}";
      }
   }

   $test = new TestChild();
   $test->testData();

 

Its output is ", , , and "

 

It cannot get a hold of the parent's data members because they're private.  Even the protected method doesn't work because the data member it modifies is private.  Changing them all to protected generates the correct output of "yo, wassup, hello, hola, and bonjour"

 

Try it yourself.

Link to comment
Share on other sites

AHHHH I just figured out why I was confused. You are indeed correct, and this is what I originally thought, However, I had child methods that did something like this

class parentClass {
private $var1, $var2, $var3;

protected function do(){
//do stuff
}
}

class child extends parentClass{
public function setVar1($var){
$this->var1 = $var;
}
}

 

If i were to call setVar1 what I originally thought was happening was that function was setting $var1 in the parent class. However, it appears that it just makes a var1 in the child class. I get it now.

 

However, I have a different question while I have your attention. Originally, I had the set file function in my parent class


abstract class MasterConverter {

protected $file, $system, $uifile, $format;
protected $allowedFiles;//this is an array

abstract public function execute();
abstract protected function createCommand(); //Changing stuff.
abstract protected function setFile($file);
abstract protected function setFormat($format);

protected function setuiFile($uifile) {	
$this->uifile = $uifile;	
}
public function setFile($file) {
//echo $file."<br />";
$ext = end(explode('.', $file));
//echo $ext."<br />";
if (!in_array($ext, $this->allowedFiles)){//note I use allowefFIles but it hasn't been defined yet
echo "Invalid file type!";
exit();
}

$this->file = $file;

$newFile = sha1(substr($file, 0, strrpos($file, '.')));
$this->setuiFile($newFile);//seems to be a problem with this
}	

}

 

In my child class I want to use the setFile function, but define my own allowedFiles array. like so

class childClass extends MasterConverter {
//other stuff

$allowedFiles=array("jpg", "txt"/* etc */);
}

 

However, when I call the set file function, it doesn't seem to be able to use the childs allowFiles class. Is there a way I can set the parent method to use the child's data?

Link to comment
Share on other sites

Yeah, classes don't quite work like that.  You need to keep in mind scope - a child has all of a parent's public and/or protected attributes, but a parent has none of the child's attributes.  Therefore, the parent class can't access what's defined in the child class (in your case, the array).

 

The simplest solution is to put that method definition in the child class.

Link to comment
Share on other sites

Yeah, thats what I've been doing because it didn't work. That makes sense anyways, if parents could access child data, things might get screwy. Is there a way to make a data member abstract? so that it has to be defined in the child? if it were abstract would I be able to use it in parent methods? like

class master {
abstract protected $something;

protected function somethingElse(){
echo $this->something;
}
}

class slave extends master {
protected $something = "I am something";

public function slave() {
$this->somethingElse;
}
}

 

I tested this, and it doesn't work, which leads me to believe that you can't make attributes abstract. Well, not really believe,  its impossible, or at least the error message seems to think so.

 

I know I could put the method def in the child class (right now its an abstract method anyways) and that would be the simplest way, but are there any other solutions? or is what i want to do impossible.

Link to comment
Share on other sites

The only part of the method that is child specific will be the allowed file types. All subclasses of that parent will have a setFile() method, which will pretty much always look the same, baring the $this->allowedFiles array (which will be different for every class, but every class will have one). I guess I could always just override the setFile function, do the allowedFiles test, and then call the parent function.

 

Oh well, I guess I will have to define it in every sub class. Thanks for all the info though! been a big help

Link to comment
Share on other sites

Could you try something like:

 

abstract class Master
{
   protected $fileTypes;

   public function setFile($file)
   {
      if (isset($fileTypes))
      {
         // compare the file against the array
      }
   }
}

class Child extends Master
{
   public function __construct()
   {
      $this->fileTypes = array ( /* allowed file types for this class */ );
   }
}

 

The parent class declares the $fileType member, but what it contains is dependent on the child classes, and set in their constructors.

Link to comment
Share on other sites

Something like this (tested and working):

 

<?php
   abstract class Output
   {
      protected $words;

      public function Display()
      {
         if (isset($this->words) && is_array($this->words))
         {
            foreach($this->words as $item) { echo "$item, "; }
         }
      }
   }

   class Greetings extends Output
   {
      public function __construct()
      {
         $this->words = array("Hi", "Hello", "Hola", "Bonjour");
      }
   }

   class Goodbyes extends Output
   {
      public function __construct()
      {
         $this->words = array("C'ya", "Bye", "Until next time", "Au revoir");
      }
   }

   $greetings = new Greetings();
   $goodbyes = new Goodbyes();

   $greetings->Display();

   echo "<br /><br />";

   $goodbyes->Display();
?> 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.