Inheriting From Abstract Classes

  • (2 Pages)
  • +
  • 1
  • 2

18 Replies - 828 Views - Last Post: 04 October 2012 - 12:26 PM Rate Topic: -----

#1 Tenderfoot  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 160
  • Joined: 21-March 12

Inheriting From Abstract Classes

Posted 03 October 2012 - 03:36 PM

Hello all.

I'm in a bit of trouble understanding how to create and extend an abstract class. I am doing an assignment for school at the moment - and am also having trouble understanding what the teacher wants me to do at some parts. I'm going to try to keep this brief and to the point.

I will post two classes, with my instructions for each (which I'd also appreciate your opinion on).

Instructions for my abstract class:

Quote

Write the abstract class starfsmadur (employee).
It should have 3 variables.
Fornafn, eftirnafn, and titill (first name, last name, and title, respectively).
And getters and setters for each.
The constructor in the function should take in all the variables. (I presume he meant to say class).
The class should also implement the magic function __toString() which prints out his combined name and his title. It should also define the abstract functions tekjur() (income)


My attempt at making said abstract class: - I try to put questions in the comments where appropriate.
abstract class Starfsmadur
{
        //My variables - why should an abstract class have these?
	private $fornafn; //first name
	private $eftirnafn; //last name
	private $titill; //title
	
        //Getters and setters for the variables, should these be abstract public functions?
	public function setFornafn($fornafn)
	{
		$this->fornafn = $fornafn;
	}
	
	public function getFornafn()
	{
		return $this->fornafn;
	}
	
	public function setEftirnafn($eftirnafn)
	{
		$this->eftirnafn = $eftirnafn;
	}
	
	public function getEftirnafn()
	{
		return $this->eftirnafn;
	}
	
	public function setTitill($titill)
	{
		$this->titill = $titill;
	}
	
	public function getTitill()
	{
		return $this->titill;
	}
	
        //The constructor that takes in the variables
	public function __construct($fornafn, $eftirnafn, $titill)
	{
		$this->setFornafn($fornafn);
		$this->setEftirnafn($eftirnafn);
		$this->setTitill($titill); 
	}
        //The __toString() function
	public function __toString()
	{
		return "Nafn: " . $this->fornafn . " " . $this->eftirnafn . " Titill: " . $this->titill; 
	}
	
        //The abstract function tekjur()
	protected abstract function tekjur(); 
}



Now for the class that I created that attempts to extend the abstract class.

My instructions:

Quote

Now write the class forstjori (CEO).
It inherits starfsmadur (employee) and has one variable, laun (salary).
Its constructor should take in fornafn, eftirnafn, and laun. (first name, last name, and salary, respectively.)
Laun (salary) is of the type int.
Implement the __toString() function and the ones needed for the laun (salary).


The code: Again I try to put questions in the comments where appropriate.

class Forstjori extends Starfsmadur
{
        //The only variable I'm supposed to have in this class
	private $laun; //salary
	
	function setLaun($laun) //setSalary
	{
		$this->laun = $laun; 
	}
	
	function getLaun() //getSalary
	{
		return $this->laun; 
	}
	
        //This function, as instructed, is supposed to take in the variables
        //fornafn, eftirnafn, and laun (first name, last name, and salary)
        //Note that fornafn & eftirnafn only exist in the abstract parent class
	function __construct($fornafn, $eftirnafn, $laun)
	{
		//parent::__construct($fornafn, $eftirnafn);
                //The line above won't work - I have no title parameter nor was I instructed to have one.
                //Perhaps I should create setters and getters for fornafn and eftirnafn somhow
                //And call the setters/getters in the abstract class? 
		$this->setLaun($laun);
	}
	
        //The tekjur function (income) 
        //I have no clue what to do with this one, it is abstract
        //As I was instructed to do, but as to what to do with it, I haven't the faintest idea
	function tekjur()
	{
		//Return laun?
	}
	
        //Implementing (although not really)? the __toString() function
        //Was I supposed to make it public abstract?
	function __toString()
	{
		parent::__toString() . " tekjur eru $this->laun"; 
	}
}



I would really appreciate it if someone could point me in the right direction, considering the instructions. A fair bit of the variables / functions were in Icelandic but I tried to repeat them as often as possible in English to avoid confusion.

Is This A Good Question/Topic? 0
  • +

Replies To: Inheriting From Abstract Classes

#2 codeprada  Icon User is offline

  • Changed Man With Different Priorities
  • member icon

Reputation: 943
  • View blog
  • Posts: 2,353
  • Joined: 15-February 11

Re: Inheriting From Abstract Classes

Posted 03 October 2012 - 06:44 PM

An abstract class is a class that can't be instantiated or used without being inherited. From the looks of it you got that part correct. The abstract methods must be defined in the child classes. So basically when you define a method as abstract you're saying that you must create your own version of that method within the child classes.

For PHP to acknowledge that you've done so the method definition must be the same.
Example
abstract class A
{
    abstract protected function doSomething();
}

class B extends A
{
    protected function doSomething() { return null; }
}



Note that they are protected. You've omitted the scope identifier in the child class definition. This will raise an error. The keyword abstract also goes before the scope identifier. You may want to change that.

Have a look at Class Abstraction on php.net
Was This Post Helpful? 1
  • +
  • -

#3 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2836
  • View blog
  • Posts: 9,740
  • Joined: 08-August 08

Re: Inheriting From Abstract Classes

Posted 03 October 2012 - 07:50 PM

You're forgetting the magic function __tostring() which is in the instructions.
<?php

abstract class example {
	protected $firstname;
	protected $lastname;
	
	function __tostring() {
		return "Magic: ".$this->lastname.", ".$this->firstname."<br>";
	}
}

class myclass extends example {
	
	function __construct($first, $last) {
		$this->firstname = $first;
		$this->lastname = $last;
	}

}

$test = new myclass("Joe","Smith");

echo $test;


Was This Post Helpful? 1
  • +
  • -

#4 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3402
  • View blog
  • Posts: 9,611
  • Joined: 08-June 10

Re: Inheriting From Abstract Classes

Posted 03 October 2012 - 11:46 PM

Quote

//The tekjur function (income)
//I have no clue what to do with this one

the question would be, whether there is a difference between salary and income (taxes, maybe?).
Was This Post Helpful? 1
  • +
  • -

#5 Tenderfoot  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 160
  • Joined: 21-March 12

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 08:35 AM

View PostCTphpnwb, on 03 October 2012 - 07:50 PM, said:

You're forgetting the magic function __tostring() which is in the instructions.
<?php

abstract class example {
	protected $firstname;
	protected $lastname;
	
	function __tostring() {
		return "Magic: ".$this->lastname.", ".$this->firstname."<br>";
	}
}

class myclass extends example {
	
	function __construct($first, $last) {
		$this->firstname = $first;
		$this->lastname = $last;
	}

}

$test = new myclass("Joe","Smith");

echo $test;



I actually do have the magic __toString() function up there. And I do find your code very agreeable and understand it better than what I was instructed to do.

However, in your example, you leave out something my teacher asked me for, which is the variable $titill (or $title). That variable exists in the abstract class but not in the child class. The abstract class's __construct is also supposed to take in the $titill variable.

But first one question about your code:

In the abstract class you have the variables protected (which means a child class can access them, I get that part) but in the child class you have a __construct and in it you simply write:

$this->variableInAbstractClass = parameter;


Does this automatically change the protected variable in the abstract class to what you said in there? And if so, can I use the get function I have in my abstract class to obtain the value of firstName/lastName?

I've altered my child class __construct like this:

	function __construct($fornafn, $eftirnafn, $laun)
	{
		parent::setFornafn($fornafn);
		parent::setEftirnafn($eftirnafn);
		$this->setLaun($laun);
	}



Is that bad coding practice? I was asked to implement a setter/getter in the abstract class and thus I figure I'd better use it. But if I can achieve the same with $this->fornafn I also find that very cool. Thanks you for your input though, I'm going to experiment a bit and see what I can do.

View PostDormilich, on 03 October 2012 - 11:46 PM, said:

Quote

//The tekjur function (income)
//I have no clue what to do with this one

the question would be, whether there is a difference between salary and income (taxes, maybe?).


Yeah, I was thinking the same, but seeing as he didn't ask for anything I'm assuming that income would be the same as salary, but then again, I'm only supposed to have the $salary variable in that class, so I'm not sure what to do in there. $this->laun = $laun; seems rather silly and useless.
Was This Post Helpful? 0
  • +
  • -

#6 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2836
  • View blog
  • Posts: 9,740
  • Joined: 08-August 08

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 09:05 AM

$this->variableInAbstractClass = $parameter;


sets the value of the the variable in the instance of myclass (in this case $test), which inherited example's properties. Nothing is changed in example because it's an abstract class and there is no instance of it.

$this-> 

is the same as:
self::


I don't think you want
parent::

Was This Post Helpful? 1
  • +
  • -

#7 Tenderfoot  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 160
  • Joined: 21-March 12

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 09:15 AM

Update: I got this to work. I need an opinion about my child class's __toString() function though.

Here's my __toString() function:

function __toString()
	{
		return parent::__toString() . " laun eru $this->laun"; 
	}



I then continue to run it like this:

require_once 'class.starfsmadur.php';
require_once 'class.forstjori.php';

$forstjori = new Forstjori("John", "Johnson", 1000000);

echo $forstjori; 



Now, the output is: Nafn: Ragnar Ragnarsson Titill: tekjur eru 1000000.

The first part: "Nafn: firstname lastname Titill:" is a result of the parent (abstract) class's __toString() function, and the last part from the child class solely.

My question is, considering that my child class's smith wasn't supposed to take in Titill (title), should I be doing it this way? It will display en empty title every time. But at the same time, I thought I was supposed to inherit and add to the function somehow.

View PostCTphpnwb, on 04 October 2012 - 09:05 AM, said:

$this->variableInAbstractClass = $parameter;


sets the value of the the variable in the instance of myclass (in this case $test), which inherited example's properties. Nothing is changed in example because it's an abstract class and there is no instance of it.

$this-> 

is the same as:
self::


I don't think you want
parent::


I hadn't read that prior to my reply. Thanks for clearing this up, I appreciate it. So seeing as I'm still supposed to put getters/setters in the abstract function, perhaps I should declare the getters/setters as abstract as well? That'd make sense.

Then, in the case of the child class, which doesn't have one of the abstract class's variables, I could declare the getter/setter for that variable abstract in the child class in order for me not to have to implement it, or something along those lines. But again, thanks for helping me with this, I think this concept is coming together for me a bit more.

This post has been edited by Tenderfoot: 04 October 2012 - 09:17 AM

Was This Post Helpful? 0
  • +
  • -

#8 Tenderfoot  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 160
  • Joined: 21-March 12

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 09:22 AM

--------

I have a new question, I realize that I can set the variables with $this->variable (most likely because they're protected variables) but for some reason if I use $this->setVariable (from the abstract class) to set the protected variables up there, when I then proceed to call the variables in the child class they come up empty. So erm, perhaps the getters/setters shouldn't do anything at all?

I'd just declare them like this in the abstract class:

abstract public function setVariable($variable);

And

abstract public function getVariable();

Am I on the right track or completely off?

This post has been edited by Tenderfoot: 04 October 2012 - 09:24 AM

Was This Post Helpful? 0
  • +
  • -

#9 Tenderfoot  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 160
  • Joined: 21-March 12

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 09:33 AM

To put it more directly: Should all functions in an abstract class be abstract?

I could make all the get/set functions abstract but it seems like it would kind of defeat the purpose of inheriting that class, except for that it forces you to implement everything an abstract class has. And if I did make every get/set function abstract, I would have to implement all of them in the child class, and there's one get/set for a variable that the child class isn't even supposed to have. So that's somewhat problematic.
Was This Post Helpful? 0
  • +
  • -

#10 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2836
  • View blog
  • Posts: 9,740
  • Joined: 08-August 08

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 10:12 AM

It seems to me that all methods of an abstract class are by definition abstract. I don't believe declaring them so will make a difference. All it does is force you to define the function in the children.
Was This Post Helpful? 1
  • +
  • -

#11 Tenderfoot  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 160
  • Joined: 21-March 12

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 10:40 AM

View PostCTphpnwb, on 04 October 2012 - 10:12 AM, said:

It seems to me that all methods of an abstract class are by definition abstract. I don't believe declaring them so will make a difference. All it does is force you to define the function in the children.


Ahh, I see. I'm not sure if I want that really. Ugh. I feel like I understand the concept of abstract classes, it's just the instructions that I don't get (which makes me want to kill myself after hours and hours of trying). But I'm always like that, every part of everything has to be crystal clear. I'm stuck in a vicious cycle where I attempt to understand over and over again and get progressively more annoyed while doing so.

But erm. Can I ask you a simple question? Or simple for someone who knows. We use set functions because we may want to set constraints on what the variable we're setting can contain. Now, although that's not part of the project, that's just something I'm used to doing.

In the child class, we're only supposed to have 1 variable. And I have a get/set function for that variable in said class. Now the other two variables that are in the abstract class are not declared in the child class, but I know I can reach them with $this->variableName. Which is good. But I can't use $this->setVariable to set the variable with the set function in the abstract class. So I would feel tempted to make the get/set for firstName/lastName abstract in the abstract class, and implement them. But if I did that, I'd feel like I'd be repeating myself.

And also, I'd feel like it was inconsistent if I only made firstName and lastName abstract and not title (fornafn, eftirnafn, titill). I wouldn't want title to be abstract because clearly I'm not supposed to use title in the child class. So I don't know. I want to use set functions, which I'm told to place in the abstract class, but I don't know how to go about this. I really hate how the instructions are hurting my head, a lot.
Was This Post Helpful? 0
  • +
  • -

#12 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 3402
  • View blog
  • Posts: 9,611
  • Joined: 08-June 10

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 10:45 AM

View PostTenderfoot, on 04 October 2012 - 06:33 PM, said:

To put it more directly: Should all functions in an abstract class be abstract?

no. what about helper methods that all child classes can use?

actually, you donít even need an abstract method in an abstract class (though when you have an abstract method, the class must also be abstract).

on the other hand side, if you only have abstract methods in an abstract class, chances are that an Interface would suffice.
Was This Post Helpful? 1
  • +
  • -

#13 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2836
  • View blog
  • Posts: 9,740
  • Joined: 08-August 08

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 10:48 AM

You don't access the variables in the abstract class. The child inherits them. Using $this-> accesses the instance of that variable generated when you used new.
Was This Post Helpful? 1
  • +
  • -

#14 Tenderfoot  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 160
  • Joined: 21-March 12

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 10:52 AM

View PostDormilich, on 04 October 2012 - 10:45 AM, said:

View PostTenderfoot, on 04 October 2012 - 06:33 PM, said:

To put it more directly: Should all functions in an abstract class be abstract?

no. what about helper methods that all child classes can use?

actually, you donít even need an abstract method in an abstract class (though when you have an abstract method, the class must also be abstract).

on the other hand side, if you only have abstract methods in an abstract class, chances are that an Interface would suffice.


Ahh. When you say helper methods, you mean like my __toString method, right (or possibly get values or anything)?

I could see how those would be useful in theory. However, considering that the abstract class has 3 variables, my __toString() therefore writes out all 3 of these variables. But then, my child class has only 2 of those variables, plus an extra variable, rendering the __toString() method useless because it writes out a variable that doesn't apply to the child class. This is partially what's been bothering me.

And the instructions do tell me to implement the __toString() function in the child class. And the way I do that (basically just write a new one) renders having the __toString() function in the abstract class useless. So because that makes no sense to me, I erm, find the whole thing very confusing.
Was This Post Helpful? 0
  • +
  • -

#15 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2836
  • View blog
  • Posts: 9,740
  • Joined: 08-August 08

Re: Inheriting From Abstract Classes

Posted 04 October 2012 - 11:10 AM

No, your child class inherits all of the abstract class variables.

I think your teacher wants to demonstrate that the child class will overload the abstract class definition of the function.
Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2