I have a class PlaylistTrack that I want to extend class Song.
When I construct Song I pass in an array of data like artist, title etc.
When I construct PlaylistTrack I want it to have all song's methods as well as the new methods it introduces.
But I also want to pass in the specific song in its constructor.
So I'm doing this:
class Song {
function __construct( $song_data ) {
$this->_data = $song_data;
// etc
}
}
And then this. Don't shoot me!
class PlaylistTrack extends Song {
function __construct( $song ) {
// call the song's constructor again in the context of this class
// to give access to its methods.
parent::__construct( $song->_data );
// other PlaylistTrack-specific material to go here
}
}
This feels peculiar, to say the least. Is it ok? Is there an alternative?
The constructor is inherited automatically when extending a class. If you aren't planning to add functionality to your existing constructor, you don't need to polymorph it.
If you do want to add functionality to it, what you've done is perfectly fine.
Related
I am wondering if such this subclassing structure is possible in PHP. If this is a duplicate I apologize as I couldn't figure out what this process would be called and the only I could find was a closed question with no answer.
I am working with multiple classes. For example we will say Main and User.
The Main class will hold all of the initiation code. So
class Main{
//Setters for core variables and data needed to make calls
...
protected function fetchInfo(){
//Do Stuff to return info from other source(Curl calls in my case)
}
}
and User
class User extends Main{
public function getName(){
$data = $this->fetchInfo();
return $data['name'];
}
}
But instead of having it where I would. Do $exampe1 = new Main(...); to set varaibles, and $example2 = new User(); to call the subclass to do $example2->getName(); is there a way to do something like $example = new Main(); whcih could then call the subclasses when needed like $example->User->getName();?
I know there are a lot of different ways this could be handled, but I want the classes separate for organization and I plan on having a lot of subclasses that need to pull info from that main class and would like to know if there is a way they can be linked in that fashion.
EDIT: The reason I dont want to just call User calls to get the function is I'll end up having 15+ classes that handle the returned data differently and making wonder if there was a better way than making a new Object for each one if I want to use it.
A "Main" is not a "User" so I would say this type of subclassing is a poor choice.
I might instead look at injection.
class MainDataHandler {
//...
}
class User {
private $main;
public function __construct(MainDataHandler $main) {
$this->main = $main;
}
public function getName() {
return $this->main->getData('name');
}
}
The benefits of injection is that your classes can work and be tested independently without dependencies on another class to do the work. Also if "Main" ever changes you your User class isn't dependent on how the new Main works.
I'm changing my class structure around to store common database methods in one class. Then extending it from a child class. This should cut down on code but also allows me to overwrite the parent methods when I need to.
I've done the following, for this example I've simplified to the basics compared to the original code which contains more classes.
class parent_object{
private $table_name;
public function all_records(){
$sql = "SELECT * FROM ".$this->table_name;
return $this->execute_sql($sql);
}
}
class child_object extends parent_object{
protected static $table_name="tbl_name";
public function __construct(){
parent::__construct(self::$table_name);
}
}
I want to call the all_records() statically to save myself creating a new object every time.
I'm stuck having to instantiate the child and then call the parent method
$child = new child_object();
$all = $child->all_records();
What I really want to be able to call the parent method statically:
$all = child_object::all_records();
I understand why I can't do it with my code, but would like some way that the child instantiates first then accesses the parent method.
I could write all_records() method in the child_object to instantiate itself and call the parent all_records() but that sort defeats the purpose of extending to cut down on code and the same methods in my child class.
I'm sure its quite simple or some new high level oop function can do it.
Thanks for your help.
The answer is relatively simple, you can turn all your properties into static properties, and then use static:: instead of self::.
http://php.net/manual/en/language.oop5.late-static-bindings.php
Solving your problem this way is considered a bad practice though. Good luck.
You could do something like this:
class child_object extends parent_object
{
protected static $table_name="tbl_name";
public static function factory()
{
return new child_object();
}
public function __construct()
{
parent::__construct(self::$table_name);
}
}
Then when you use it you just do:
$all = child_object::factory()->all_records();
I'm creating a website but, in order to further my coding skills, I'm trying to do it utilising the power of OOP.
I'm using classes to validate form input so thought I'd have a 'parent' validation class and then child classes for each form that gets submitted (i.e. login class, registration class etc) that would take care of putting the right values into the database etc.
The code I've seen has the parent being constructed from the child's constructor. However, I've not done that but my class seems to work anyway?
Could someone explain to me why we call the parent constructor from the child?
Also, is my code only working because I have 'public' functions (methods) in my parent? (is this potentially an issue)?
My code (abridged version for clarity) is below:
class Validation_Class
{
public function __construct()
{
// constructor not needed
}
public function is_genuine_email_address($email) {
// code to validate email are genuine here...
}
}
My child class looks like...
class Login_Class extends Validation_Class
{
public function __construct()
{
// I don't call parent::__construct() from here
// should I be doing?
// I can still access parent methods with $this->is_genuine_email_address
}
}
All my functions (methods) in my Validation_Class are 'public' and when I instantiate my child class I can call any of the Validation Class methods with:
$className = "Login_Class";
$thisClass = new $className();
It is not nessecary to call the parent constructor
class Parent {
//maybe just holding some constants
public $database = 'mydatabase';
}
class Child extends Parent {
public function myFunction() {
if ($this->database == 'myDatabase') {
// you can access the parents data without calling a constructor
}
}
}
Is good. But if you want to benefit from something the parent has to do itself in order to work properly, a call to the parent __construct could be needed - like
class Parent {
public $database = null;
public function __construct() {
// example -> login to database
}
}
class Child extends Parent {
public function __construct() {
parent::__construct();
// .. further code
}
public function myFunction() {
// do something, like executing a query
$this->database->executeQuery($SQL);
}
}
In PHP "OOP", which is not real OOP like you see in other languages, constructors are just shorthands for instantiating the resulting object. It would be a hell if we over and over should call
$object = new MyClass();
$object->instantiate()
so calling __construct or new ClassName() is easier. But it is not absolutely needed for the class-successors to work properly, that they call constructors up in the class-hierarchy. Unless, of course, some certain initialization is needed in one of the class parents to let the successors work properly.
From an architecture perspective this would not make much sense. Because using OO inheritance is not just about extending a class in the code but also also designing and structuring your class hierarchy in such a way that it makes sense.
From a logic structuring stamp point I would not imagine a Login class to inherit from a validation class. Rather I might have a validation class object as a member of the Login class and use its functions to perform validations.
From inheritance perspective always remember that we should strive to have classes that represent 'Objects' and not 'Actions'. Of course we can have classes for Login and Validation actions, but actions rarely inherit in a parent-child fashion. They complement each other better an class members.
Calling a parent class, be it constructor or a standard method is not mandatory. It is required if you are having part of an action specified in the parent and more fine-grained action will be defined in the child.
The rule of the thumb is that as you traverse up an inherited class chain it becomes more and more generic and as you traverse down, it becomes more and more specialized.
Rather than using inheritance, using Strategy pattern for validation is one of the popular patterns available. This makes the code more modular and extendible,
Validating Incoming Data with the Strategy Design Pattern
I am new to PHP and just get into OOP. I have few generic methods used to set and get properties. I use them quite often in almost all the classes, i put those methods in a class and extends other classes from it. Now i can access the methods from child class but dont know how set and get attributes of child class through them ... parent class base.php
class Base
{
public function __construct()
{
}
function __set($propName, $propValue)
{
$this->$propName = $propValue;
}
function setProperties(array $data)
{
foreach($data as $propName => $propValue)
$this->$propName = $propValue;
}
function __get($propName)
{
return (isset($this->$propName))? $this->$propName : "Invalid property!";
}
function getProperties(array $properties)
{
foreach($properties as $propName)
$propVals[$propName] = $this->$propName;
return $propVals;
}
}
child class categories.php
class categories extends Base
{
private $id;
private $pid;
private $title;
private $status;
public function __construct()
{
parent::__construct();
}
}
and i called it like
$objCat = new categories();
$objCat->setProperties(array('id'=>'10', 'pid'=>'6'));
print_r( $objCat->getProperties(array('id', 'pid')));
Need little guidance here. If its the right way? or at least is it possible to do it like this? if so how to accomplish this ...
thanks
Extending a class is something you only want to do when you can say class categories is a class Base. Something like that sort of utility class you have their is almost always the wrong way to go. PHP also has introduced something called traits for copy/paste code. However my personal preference is that it is something you will never want to use, because it tightly couples the traits to your class, which is something you want to avoid.
See for more information the Liskov Substitution principle in SOLID programming.
If it was up to me I would avoid those magic getters / setters either way and just add your own getters / setters methods to the class.
The mistake about some base class isn't something only you are doing (hell even I have done it in the past). Think about some class Database and a class Article. Because the Article class needs access to the database many people let the class extend the Database class. This isn't correct because an article isn't an database. Instead an instance of the database class should be injected into the article class by using dependency injection. The instance should either be injected into the class constructor (if all or many methods need access to it) or just the methods that need it. So when extending a class you have to be able to say class B is a class A.
Some other notes about your code:
Always make your class names PascalCase. This is not really required to make your code work, but it follows a naming convention often used.
And my personal preference a bit: please always add curly braces to your foreach statements. It is more clear what is happening when other people are reading your code.
Lets say I have a class called PageBuilder which I instantiate, send parameters to and call functions from through my index file (which acts as a front controller). There are three sub classes associated with the PageBuilder class: Head, Body and Foot, that are accessed by PageBuilder which basically abstracts them for index.
So in theory you could instantiate PageBuilder and have full access to the other classes as if they were part of PageBuilder.
How can I implement a design like this in PHP5 using any combination of classes, abstract classes and interfaces?
I don't think the above is possible with PHP5, not necessarily because PHP has its limitations but maybe because I am going about the design of my application the wrong way.
Common examples of OOP in PHP don't suffice to help me understand how to structure a more complex design.
Thanks.
Some of the other answers are on the right track. The problem you're running into is that your PageBuilder class is doing too much. Just the name sounds wrong for what you're trying to do with it. A PageBuilder sounds like something that would assemble a bunch of parts together into a Page. Let's call these parts Section. Then, what you want to do is use composition, as several of the answers have hinted at.
Inheritance is often described as an is-a relationship, as in if your Section classes extend the PageBuilder class, then a Section is a PageBuilder. What you want though is a has-a relation ship, as in your PageBuilder class has a (or many) Section(s). Any time you need a has-a relationship, you should be looking toward composition rather than inheritance.
So here might be your class hierarchy:
abstract class PageBuilder
{
//#var Section
public $header;
//#var Section
public $body;
//#var Section
public $footer;
public function render()
{
echo $this->header.$this->body.$this->footer;
}
}
class Section
{
protected $content;
}
class LoginPage
extends PageBuilder
{
public function __construct()
{
$this->header=new Section(...);
$this->footer=new Section(...);
$this->body=new Section(...);
}
}
At this point, you're really kind of re-inventing the wheel by making a crappy MVC system. If this is for a project (rather than for learning), you should consider using one of the MVC frameworks for PHP. (I recommend Kohana, but there are several questions regarding the best PHP versions on Stack Overflow.) If you're thinking of these kinds of things, MVC probably won't be a great leap for you.
From what I understand here you could use the composite pattern
http://en.wikipedia.org/wiki/Composite_pattern
Your controller index has only access to an object that implements an interface IPageBuilder (or a name similar), with some standards function like "generatePage". This object would in reality be some kind of container that contain other object of type IPageBuilder. Those leafs object would be able to build some subsection of the page, like Head, Body and Foot. Each of those leaf object would be of a different class, but they will implement the IPageBuilder interface. When your index object call "generatePage", the container will call in order the "generatePage" method of each of its leaf objects, that will in turn take care of rendering the HTML.
Using this approach, if your Body class become too big, you can always turn it into a container that implements the IPageBuilder interface, for example a blog post Body could consist of an Article object and a CommentList object. The body object would then only propagate the "generatePage" method to its children object.
To create your IPageBuilder object, you can use a factory patterns
http://en.wikipedia.org/wiki/Factory_method_pattern
In all honesty, I have tried those kind of approach in the past to generate my HTML and found them to be kind of overkill. My suggestion would be to use a templating engine instead, like Smarty. Your designer will love you (or hate you less) if do that ^^.
http://www.smarty.net/
If you want to know how to use interfaces in PHP, not that it's very hard...
http://ca.php.net/manual/en/language.oop5.interfaces.php
So if I understand correctly you want Head, Body, and Foot to automatically construct as children of PageBuilder?
There are a couple of ways you could maybe do this.
1) Create variables inside of PageBuilder to hold the classes and use a __call method
class PageBuilder{
private _head;
private _body;
private _foot;
function __construct(){
$this->_head = new Head();
$this->_foot = new Foot();
$this->_body = new Body();
}
function __call($name, $args){
if(method_exists($this->_head, $name)) call_user_func_array(array($this->head, $name), $args);
// Repeat for other classes.
}
}
The problem here obviously being if two classes share the same method then the first one to come up wins. You could probably modify it to pick a class based on the function name pretty easily.
2) Chain everything down.
Abstract class Page{
}
class Head extends Page{
}
class Body extends Head{
}
class Foot extends Body{
}
class PageBuilder extends Foot{
}
Either way its somewhat hacked, you just kind of have to make it work.
PHP only allows you to extend one parent class (which can in turn extend another parent class, etc.). There are no interfaces, meaning you can't inherit functions or properties from multiple interfaces as you could in C++.
As such, you will probably need to do something more like this:
class PageBuilder {
protected Head, Body, Foot;
public function __construct($request) {
$view = $this->getView($request);
$this->Head = new PageSection('head.tpl');
$this->Body = new PageSection($view);
$this->Foot = new PageSection('foot.tpl');
}
private function getView($request) {
// #todo return the template filename/path based upon the request URL
}
}
class PageSection {
private $template;
public function __construct($template) {
$this->template = $template;
}
public function render() {
// #todo process and output the $this->template file
}
}