i want to show a name.name may be in uppercase or in lowercase this will be depend on which class i will pass.i have to approach one is using class and second is interface which one is better and why ?
Solution using Class
class User{
}
class Iuser extends User{
private $name;
function __construct($name){
$this->name = $name;
}
function getName(){
return strtoupper($this->name);
}
}
class Wuser extends User{
private $name;
function __construct($name){
$this->name = $name;
}
function getName(){
return strtolower($this->name);
}
}
class Name{
public $u;
function __construct(User $u){
$this->u = $u;
}
function getName(){
$name = $this->u->getName();
return "Hi My Name is ".$name;
}
}
$name = "Deval Patel";
$iu = new Iuser($name);
$wu = new Wuser($name);
$user = new Name($wu);
echo $user->getName();
Solution Using Interface
interface User{
public function getName();
}
class Iuser implements User{
private $name;
function __construct($name){
$this->name = $name;
}
function getName(){
return strtoupper($this->name);
}
}
class Wuser implements User{
private $name;
function __construct($name){
$this->name = $name;
}
function getName(){
return strtolower($this->name);
}
}
class Name{
public $u;
function __construct(User $u){
$this->u = $u;
}
function getName(){
$name = $this->u->getName();
return "Hi My Name is ".$name;
}
}
$name = "Deval Patel";
$iu = new Iuser($name);
$wu = new Wuser($name);
$user = new Name($iu);
echo $user->getName();
Using the interface solution the getName() method is defined but not implemented in User interface (not shown in your code), so each class implementing it has to define the behaviour to get the name, whilst using abstract classes you may define the standard way to get the name, and override or overload the method in child classes when necessary.
So for your code, I think the best solution is the abstraction.
Remember to use interfaces when you want to force the developer to code the getName() method, and for abstract classes just to allow the developer to use the parent method getName(), or override/overload if necessary. Interfaces gives you more control and code reutilization.
Review the PHP object interfaces doc and PHP class abstraction doc, it may shed some light on your doubt.
I would use classes because you can reuse some code.
abstract class User
{
protected
$name;
public function __construct($name)
{
$this->name = $name;
}
abstract function getName();
}
class Iuser extends User
{
public function getName()
{
return strtoupper($this->name);
}
}
class Wuser extends User
{
function getName(){
return strtolower($this->name);
}
}
This way you can still use polymorphism and reuse some common code.
It's better then interface because the code reuse. You can still use an interface for the abstract class User but I think it would be an overkill.
Related
EDIT: Really sorry screwed up original example. More explanation at end.
I am new to OOP finding it useful, finding it confusing.
I have looked and I think this must be a simple question but searched on things like "instantiation of subclass php" but could find nothing on point.
I want to instantiate an object and then later instantiate the subclass. Can I "add" the subclass to the existing instance?
class Dog
{
protected $owner;
protected $color;
public function setOwner($owner)
{
$this->owner = $owner;
}
public function setColor($color)
{
$this->color = $color;
}
}
class Bulldog extends Dog
{
protected $name;
protected $typeOfTail;
... set tail....
public function setName($name)
{
$this->name = $name;
}
}
class Beagle extends Dog
{
protected $name;
protected $typeOfSpots;
... set spots ....
public function setName($name)
{
$this->name = $name;
}
}
$myDog = new Dog;
$myDog -> setOwner("Bob");
$myDog1 = new Beagle;
$myDog1 -> setName("name");
obviously that will not work but if I do
$myDog = new Beagle;
$myDog -> setName("name");
I presume that just sets the owner to NULL?
Is there a way to pull the existing values (or duplicate the values) of a class into and instance of a subclass (I suppose I could do some sort of complicated method to pull all the values in but there a lot of them ....) Is this something easy to do in PHP or am I off on a LIMB?
It is 3.30 am and I apologise if this is really dumb but I have hit a wall these last couple of days and am getting behind. This seems like it could be useful in the current project.
Clarification: This is a hypothetical example. (No dogs involved with the project.) Say we have a brown dog owned by Fred and we populate an instance of dog (pretend it is a big class with lots going on).
The next day someone says "that dog is a beagle" (ok later in the file - this is not a great example) so we want to instantiate a Beagle class with the name Suki.
What I want is an instance of Beagle that inherits the already existing dog info.
Sorry once again. Off to bed.
General solution: (in case you already know the future subclass)
Just directly create an instance of the subclass. You can use it as an instance of the superclass. But some more information of what you're trying to achieve would be useful.
So it would work like this:
class Dog
{
protected $owner;
protected $color;
public function setOwner($owner)
{
$this->owner = $owner;
}
public function setColor($color)
{
$this->color = $color;
}
}
class Beagle extends Dog
{
protected $name;
public function setName($name)
{
$this->name = $name;
}
}
$myDog = new Beagle;
// here we call two methods of the Dog superclass
$myDog->setOwner("Bob");
$myDog->setColor("brown");
// now we call a method of the subclass
$myDog->setName("SomeName");
As you can see there is no need to add the methods of the parent class to the subclass again. They will be inherited implicitly and you can just use them on instances of the subclasses as if they are defined within the subclass.
If you omit one of these method calls the property will be null, because no default value is assigned to the properties.
Specific solution: (in case you don't know the actual subclass)
If you can't create the subclass directly, create a constructor like this:
class Dog
{
protected $owner;
protected $color;
public function __construct(Dog $dog = null) {
if ($dog) {
foreach ($dog as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
}
}
}
public function setOwner($owner)
{
$this->owner = $owner;
}
public function setColor($color)
{
$this->color = $color;
}
}
class Beagle extends Dog
{
protected $name;
public function setName($name)
{
$this->name = $name;
}
}
$dog = new Dog;
$dog->setOwner("Bob");
$beagle = new Beagle($dog);
$beagle->setColor("brown");
I did not test the code, so maybe there is still a bug in it, but it should get my point accross.
Parent and child classes
You can create 2 class, lets call one ParentClass and one ChildClass. This gives us:
class ParentClass
{
}
class ChildClass
{
}
As you can see, they are not linked in any way, shape or form, so, we need to extend the child class to use the parent, so we now have:
class ParentClass
{
}
class ChildClass extends ParentClass
{
}
Now the child speaks to the parent, so let's add a property to the parent, lets call it name:
class ParentClass
{
protected $name; //Protected means it's private, but accessible to children
}
class ChildClass extends ParentClass
{
}
Now let's add some functionality to the child, a getter and a setter:
class ParentClass
{
protected $name;
}
class ChildClass extends ParentClass
{
public function setName($value)
{
$this->name = $value;
}
public function getName()
{
return $this->name;
}
}
As you can see, it uses the $name from the parent, meaning it's value is available to the child, so we can do:
$childClass = new ChildClass();
$childClass->setName("My Name");
print $childClass->getName(); // prints My Name
And get a result!
Edit
Extra to show differentiation in the setters:
class Dog
{
protected $owner;
protected $color;
protected $name; // I'd put this here as all dogs have a name, right?
// Put the getters in here as all they do is return, they won't change (hopefully...)
public function getOwner()
{
return $this->owner;
}
public function getColor()
{
return $this->color;
}
public function getName()
{
return $this->name;
}
}
class Beagle extends Dog
{
public function setOwner($val)
{
$this->owner = $val;
}
public function setColor($val)
{
$this->color = $val;
}
public function setName($val)
{
$this->name = $val;
}
}
/**
* Added extra code to setters
*/
class Dalmatian extends Dog
{
public function setOwner($val)
{
$this->owner = "Owner: " . $val;
}
public function setColor($val)
{
$this->color = "Color: " . $val;
}
public function setName($val)
{
$this->name = "Name: " . $val;
}
}
As you can see in this example, there are 2 child classes, Beagle and Dalmatian, each with somewhat different setters for the values.
As the values are not static in the parent class, they will be different in each child, so setting one won't change the other and vica versa.
To keep values from the parent across all subclasses, use static properties as such:
class Dog
{
protected static $owner;
protected static $color; // Don't know why you'd want this kept, but okay?
}
And call using static::${variable_name}; as opposed to: $this->{variable_name};
I've been programming mainly with JAVA and have written procedural programs in PHP, but now I'm try to write some OOP bases programs in PHP and I'm facing a problem.
I've got two files , Zoo.php and Dog.php , each contains a class.
Dog.php:
<?php
class Dog {
private $name;
private $color;
public function __construct($name,$color) {
$this->name = $name;
$this->color = $color;
}
public function getName(){
return $this->name;
}
public function getColor(){
return $this->color;
}
}
And Zoo.php:
<?php
class Zoo {
private $name;
private $dogs;
public function __construct($name) {
$this->name = $name;
$dogs = array();
}
public function addDog($dogName,$dogColor){
$dog = new Dog($dogName,$dogColor);
array_push($this->dogs,$dog);
}
public function getAllDogs(){
var_dump($dogs);
}
}
echo "start";
$z = new Zoo("test_zoo");
$z->addDog("blackie","black");
$z->getAllDogs();
The code above outputs :
Fatal error: Class 'Dog' not found in C:\wamp\www\Zoo.php on line 13
I'd like to know what's wrong with the code above and how creating an object instance within another object should be done in PHP. Thanks in advance.
I gues you are not including Dog class.
<?php
include "Dog.php";
class Zoo {
/* ... */
}
Or you can use autoloading to auto include any class by default.
It's not about OOP. Just you forgot to include Dog file to use it you Zoo class :
<?php
include 'Dog.php'; // or whatever path
class Zoo { ...
Everything else should be ok and seems to be a good use of PHP OOP btw. :)
You haven't included your Dog.php in your Zoo.php. Therefore you can't create an new instance.
Just above class Zoo add this:
include("Dog.php");
class Zoo {
All you need to return function .
Three mistakes here, u'll see all of them in my code . Constructer nothing return , behave like void , so we need a method that returns dog specification.If you wanna use the classes in separate file, so u've to use php method that "include" or "require" or "require_once" etc ( see the difference of this method)
<?php
class Dog {
private $name;
private $color;
public function __construct($name,$color) {
$this->name = $name;
$this->color = $color;
}
public function getName(){
return $this->name;
}
public function getColor(){
return $this->color;
}
public function getDogs(){
return array("name"=>$this->name,"color"=>$this->color);
}
}
class Zoo extends Dog{
private $name;
private $dogs=array();
public function __construct($name) {
$this->name = $name;
$dogs = array();
}
public function addDog($dogName,$dogColor){
$dog = new Dog($dogName,$dogColor);
array_push($this->dogs,$dog->getDogs());
}
public function getAllDogs(){
var_dump($this->dogs);
}
}
echo "start";
$z = new Zoo("test_zoo");
$z->addDog("blackie","black");
$z->getAllDogs();
?>
I am trying to extend static class in PHP. What I am running into is that once I change the variable in one of the extend classes, all others classes are changes as well. This is what I am trying to do:
class Fruit{
private static $name = Null;
public static function setName($name){
self::$name = $name;
}
public static function getName(){
return self::$name;
}
}
class Apple extends Fruit{};
class Banana extends Fruit{};
Apple::setName("apple");
Banana::setName("Banana");
echo Apple::getName();
echo Banana::getName();
I have read about late static binding and the keyword static::. But I cannot think of a way how to accomplish this without having to redeclare all Fruit's methods in both Apple and Banana.
I will be happy for any help
Thank You
This works:
<?php
class Fruit{
protected static $name = Null;
public static function setName($name){
static::$name = $name;
}
public static function getName(){
return static::$name;
}
}
class Apple extends Fruit{protected static $name;};
class Banana extends Fruit{protected static $name;};
Apple::setName("apple");
Banana::setName("Banana");
echo Apple::getName();
echo Banana::getName();
Unfortunately you need to re-declare the static properties you want to specialize, but your late static binding intuition was right :)
Although you should avoid such constructions, you could solve it quite nicely:
<?php
class Fruit {
protected static $names;
public static function setName($name)
{
self::$names[get_called_class()] = $name;
}
public static function getName()
{
return isset(self::$names[$key = get_called_class()]) ? self::$names[$key] : null;
}
}
So basically you store the data in just a single class, but specific to the class the method was called on. You don't need static as $name is always part of self, but 5.3 is still required because get_called_class is also part of late static binding.
This is probably a basic question but im following this tutorial and at one point the code looks something like this.
<?php
class person
{
public $name;
public $height;
protected $social_security_no;
private $pin_number = 3242;
public function __construct($person_name)
{
$this->name = $person_name;
}
public function set_name($new_name)
{
$this->name = $new_name;
}
protected function get_name()
{
return $this->name;
}
public function get_pin_number_public()
{
$this->pub_pin = $this->get_pin_number();
return $this->pub_pin;
}
private function get_pin_number()
{
return $this->pin_number;
}
}
class employee extends person
{
public function __construct($person_name)
{
$this->name = $person_name;
}
protected function get_name()
{
return $this->name;
}
}
However when i use this
<?php include "class_lib.php";?>
</head>
<body id="theBody">
<div>
<?php
$maria = new person("Default");
$dave = new employee("David Knowler");
echo $dave->get_name();
?>
i get this error
Fatal error: Call to protected method employee::get_name() from
context '' in C:\Users\danny\Documents\Workspace\test\index.php on
line 13
The problem seems to be when i add protected to the get_name() function in the employee class but it seems to me that this is the preferred way to override in the tutorial. Any ideas?
The problem isn't that you cannot override the protected method, it's that you are calling a protected method from outside of the class.
After the class is instantiated, you can call a public method which in turn could call get_name() and you will see that the code will work as expected.
For example:
class employee extends person {
function __construct($person_name){
$this->name = $person_name;
}
protected function get_name() {
return $this->name;
}
public function name()
{
return $this->get_name();
}
}
$dave = new employee("David Knowler");
echo $dave->name();
In your example, you would probably be best making get_name() public.
"The problem seems to be when i add protected to the get_name() function in the employee class" -- this is your answer. A protected method can only be called from the very same class or subclasses, not "from the outside". Your method has to be public if you want to use it this way.
You can access get_name() within person class or employee class not outside of these two classes.
check protected visibility
http://php.net/manual/en/language.oop5.visibility.php
I have a simple question. I use a singleton which implements an abstract class. Is it possible to put the getInstance() Method and the variable $_instance in the abstract class instead of the concrete one I want to create?
Here's my code:
<?php
class Command_Log extends Command_Abstract {
private static $_instance=null;
public static function getInstance() {
if (self::$_instance==null)
self::$_instance=new self();
return self::$_instance;
}
protected function realExecute() {
}
protected function realSimulate($fileHandle) {
}
}
and
<?php
abstract class Command_Abstract implements Command_Interface {
protected $_data=array();
//private static $_instance=null;
protected $_isExecuted=false;
protected $_execute=false;
public function enableExecute() {
$this->_execute=true;
return $this;
}
protected function __construct() {
}
protected function __clone() {}
public function addData($data) {
array_push($this->_data,$data);
return $this;
}
abstract protected function realExecute();
abstract protected function realSimulate($fileHandle);
public function execute() {
if(!$this->_isExecuted && $this->_execute) {
$this->_isExecuted = true;
$this->realExecute();
}
}
public function simulate() {
$exitSystem = false;
if(!$this->_isExecuted && $this->_execute) {
$this->_isExecuted = true;
$exitSystem = $this->realSimulate($fh);
}
}
return $exitSystem;
}
}
I have many implementations of the the commands, so I don't want redundant code everywhere in my implementations. Is it possible to put these two things in the abstract class, if yes please tell me how.
If not please explain it to me why it isnt possbile. Or if I need to change something to do it, anyhow.
regards
YES WE CAN!
I have a class called Singleton that is abstract... and many classes that extends that Singleton class... this is the code:
abstract class Singleton {
private static $instances = array();
final private function __construct($_params) {
$class = get_called_class();
if (array_key_exists($class, self::$instances))
throw new Exception('An instance of '. $class .' already exists !');
//static::initialize(); //In PHP 5.3
$this->initialize($_params);
}
final private function __clone() { }
abstract protected function initialize();
public static function getInstance($_params=array()) {
$class = get_called_class();
if (array_key_exists($class, self::$instances) === false){
self::$instances[$class] = new $class($_params);
}
return self::$instances[$class];
}
}
and (for example) the class DBConnection that extends from Singleton
class DBConnection extends Singleton{
private $connexion_pdo=null;
protected function initialize(){
//connect to the DB
$this->connexion_pdo = blablalba;
}
}
although there are some problems in php 5.2.. specially with the function get_called_class() and the static::initialize()
You could also check the php site for patterns... there are lots of contributions for the singleton
Good Luck