Is there any clear difference why to use abstract for extends if we can do same in with the normal class excepts it doesnt provide the contract for eg.
abstract class Survivalneeds {
abstract public function eat(); // everyone eats but different foods which would probably work as contract
public function breathe() {
// everyone inhale o2 exhale co2 only for animals
}
}
Now
class human extends Survivalneeds {
protected function eat() {
//sometimes eat goat
// contract
}
breathe()// already extending having same functionality inhale o2 and exhale co2
}
class goat extends Survivalneeds{
protected function eat() {
//wee eat greens
// contract
}
breathe()// already extending having same functionality inhale o2 and exhale co2
}
Now the same functionality can be granted by normal class by extending except the contract method and for contract we could use interface also.
What you are saying its correct inheritance works in both cases but the idea of an Abstract class is that its some common logic shared by x classes that extend this functionality but that is not instantiable by it self because it doesn't make sense (maybe you want only to have types of cars in your system but not a generic car that doesn't have a brand)
Also if you will use regular class and interface you will be forced to create stub in a class in order to follow the contract. So you will be able to create the instance of the class. And just imagine you will use this common function in your upper class.
interface Crashable{
function crash();
}
class Car implements Crashable{
function crash(){}
function getCrashParams(){
return $this->crash();
}
}
class Volvo extends Car{
function crash(){
parent::crash(); // will be OK that it's not right
//.. specific params
return $params;
}
}
class Saab{
function crash(){
//.. specific params
return $params;
}
}
$car = new Car(); // will be ok, that it's not right
//getCrashParams() function in a Car will use the local version of the crash() and not the function of it's child that will kill the data flow
You should use an interface whenever you have a need for a contract. You should use abstract class in case there's a common functionality for some simmilar classes and you don't want to repeat the code (DRY :). Of course, it is always better to use composition, but this is not the time for this discussion :)
The problem with your code (with Survivalneeds class) is the fact the class from one side is responsible for the contract (breathe and eat methods) and from another is responsible for providing common functionality. You could change your code in following way:
interface Survivor {
public function eat();
public function breathe();
}
abstract class Survivalneeds implements Survivor {
public function breathe() {
// method's body
}
}
With such implementation responsibilities are splitted. Also it is clear that all classes that will extend Survivalneeds will need to as well fulfill Survivor contract.
Related
I currently have an abstract class which i am extending to other controllers. I have a abstract function within the abstract class which takes the value and places it in the __construct.
abstract class Controller extends BaseController {
abstract public function something();
public function __construct(Request $request) {
if (!is_null($this->something())){
$this->global_constructor_usse = $this->something();
}
}
}
My problem is that, on controllers that don't require this abstract function, I am having to place in the empty function.
class ControllerExample extends Controller {
public function something(){
return 'somethinghere';
}
}
Is there anyway to making the abstract function optional, or have a default value?
class EmptyControllerExample extends Controller {
public function something(){}
}
It is not possible to have a abstract method optional, as it is implied in PHP that all abstract methods must have an implementation.
There are legit use cases for optional abstract methods, yes: event handlers, metadata describers, etc. Unfortunately, you'll need to use regular, non-abstract methods with an empty body, and indicate in PHPDoc that they will do nothing unless extended.
Be wary, though: this can very quickly turn into code smell by diffusing a class responsability with their children. If you're dealing with generic events, you can look into Laravel's own event system, or the Observer pattern instead.
Abstract functions in a parent class, should only be used if its required by your application to implement the following method in all controllers who inherits from it, clearly it is not the case.
In this case i would make a trait. Here you create a trait which can be implemented by the classes who needs it. Notice the use keyword usage, use somethingTrait;
trait SomethingTrait
{
public function something()
{
echo "something called";
}
}
class Controller
{
use SomethingTrait;
public function run()
{
$this->something();
}
}
phpfiddle link
Another aproach could be doing a class inheritance structure, if the controllers you want to implement the methods has something in common. Where you would implement your special method in CrmController, where you still would be able to create shared methods in the abstract controller.
AbstractController
|
CrmController
|
CompanyController
For your question, 'Is there anyway to making the abstract function optional or have a default value?' No, and you are down the wrong path if you are trying to make abstract function optional. Hope my suggestions can help.
So I have a question about the difference between "when we should declare normal function" and "when we should declare abstract function" in base class. Look at my example.
In the abstract class:
abstract class Birds {
abstract public function fly();
}
class Swallow extends Birds {
public function fly() {
// This function override fly function in Birds class
echo "Implement fly function in Swallow class";
}
}
In the normal class:
class Birds {
public function fly() {
echo "Implement fly function in Birds class";
}
}
class Swallow extends Birds {
public function fly() {
// This function override fly function in Birds class
echo "Implement fly function in Swallow class";
}
}
What you can see. The fly function in Swallow class is inherited by Birds class (in all cases). They are a same thing. So I'm embarrassed and I dont know when we should declare abstract function in base class?
Thanks for your help!
Abstract functions are actually only an interface. E.g. there's no difference in your example between abstract class and if it would be an interface (that's because there's only abstract method).
//abstract class
abstract class Birds {
abstract public function fly();
}
//interface
interface Birds {
public function fly();
}
That's because abstract methods have the same purpose that interface's method. When you somewhere else create a function (or method or a class or another interface etc.), and you will require any Birds instance, you will be sure you have that abstract method avaiable, although it was not implemented in Birds.
public function sendBirdToSpace(Birds $bird) { //no matter what Bird subclass
$bird->fly(); //you're sure this method is avaiable
}
Also usually you will have more than one child class. When it comes to that, it's getting more clear about abstract method.
It's actually pretty simple. Should Birds have a default behaviour implementation of flying? That's all. If every bird should can fly, but there's no default method - make it abstract.
Taken from PHP OOP Class Abstraction:
When inheriting from an abstract class, all methods marked abstract in
the parent's class declaration must be defined by the child;
additionally, these methods must be defined with the same (or a less
restricted) visibility. For example, if the abstract method is defined
as protected, the function implementation must be defined as either
protected or public, but not private.
This is essentially saying that your Swallow class has to inherit (have) the fly() method in it if it extends the Bird class based off of its abstract definition.
The general rule of thumb when harnessing abstract methods is when you want normality among classes.
Take the following for example:
Class Car {
abstract public function make();
abstract public function model();
}
This is our "base" class. Anything that extends from this has to specify the make() & model() methods.
Class Tesla extends Car {
public function make() {}
public function mmodel() {}
}
As you see above, our Tesla class has the required methods within. If you do not include these methods, you'll have PHP errors thrown.
Note
If you're exploring this option of "container" like development, then I'd suggest that you have a good look at PHP OOP Object Interfaces too, well worth it!
I am trying to work out the best way to design my classes and I think abstract classes it the right way here, but I'm not sure! I am building a plugin for Wordpress carts that at the moment, will work for both Woocommerce and WP-Ecommerce. As these two systems have different implementations of certain functionality, such as getting an order object, I want to create a separate class for each platform.
I have the following which will contain generic methods that should be available to the classes that inherit from it. This class should never be instantiated:
class Order_Export {
}
I then have 2 more classes that will inherit from the above:
class Order_WooExport extends Order_Export {
}
class Order_WPExport extends Order_Export{
}
Is my design right here? Am I right in saying the class Order_Export should be an abstract class? What about methods that I want the class inheriting to implement? Do I simply mark the signature in the abstract class and not provide a body, or do interfaces come into play somewhere here?
How about instantiating the right class? Do I create a factory that will return one or the other?
Any advice appreciated!
That sound correct to use abstract base class, as long as you are sure to never need to instantiate Order_Export :
abstract class Order_Export
{
abstract protected function someMeth1();
abstract protected function someMeth2();
public function someMeth3() {
// Do common thing to both Order_WooExport and Order_WPExport
// using someMeth1(), someMeth2()...
}
}
Then :
class Order_WooExport extends Order_Export
{
protected function someMeth1() {
// Do something specific
}
protected function someMeth2() {
// Do something specific
}
}
Finally, the factory seems to be the right way to go too.
The book says:
The decorator pattern can be used to extend (decorate) the
functionality of a certain object
I have a rabbit animal. And I want my rabbit to have, for example, reptile skin. Just want to decorate a common rabbit with reptile skin.
I have the code. First I have abstract class Animal with everythig that is common to any animal:
abstract class Animal {
abstract public function setSleep($hours);
abstract public function setEat($food);
abstract public function getSkinType();
/* and more methods which for sure will be implemented in any concrete animal */
}
I create class for my rabbit:
class Rabbit extends Animal {
private $rest;
private $stomach;
private $skinType = "hair";
public function setSleep($hours) {
$this->rest = $hours;
}
public function setFood($food) {
$this->stomach = $food;
}
public function getSkinType() {
return $this->$skinType;
}
}
Up to now everything is OK. Then I create abstract AnimalDecorator class which extends Animal:
abstract class AnimalDecorator extends Animal {
protected $animal;
public function __construct(Animal $animal) {
$this->animal = $animal;
}
}
And here the problem comes. Pay attention that AnimalDecorator also gets all the abstract methods from the Animal class (in this example just two but in real can have many more).
Then I create concrete ReptileSkinDecorator class which extends AnimalDecorator. It also has those the same two abstract methods from Animal:
class ReptileSkinDecorator extends AnimalDecorator {
public function getSkinColor() {
$skin = $this->animal->getSkinType();
$skin = "reptile";
return $skin;
}
}
And finaly I want to decorate my rabbit with reptile skin:
$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());
But I can't do this because I have two abstract methods in ReptileSkinDecorator class. They are:
abstract public function setSleep($hours);
abstract public function setEat($food);
So, instead of just re-decorating only skin I also have to re-decorate setSleep() and setEat(); methods. But I don't need to.
In all the book examples there is always ONLY ONE abstract method in Animal class. And of course it works then. But here I just made very simple real life example and tried to use the Decorator pattern and it doesn't work without implementing those abstract methods in ReptileSkinDecorator class.
It means that if I want to use my example I have to create a brand new rabbit and implement for it its own setSleep() and setEat() methods. OK, let it be. But then this brand new rabbit has the instance of commont Rabbit I passed to ReptileSkinDecorator:
$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());
I have one common rabbit instance with its own methods in the reptileSkinRabbit instance which in its turn has its own reptileSkinRabbit methods. I have rabbit in rabbit. But I think I don't have to have such possibility.
I don't understand the Decarator pattern right way. Kindly ask you to point on any mistakes in my example, in my understanding of this pattern.
Thank you.
Sounds like you're trying to force the use of a particular pattern that doesnt fit the problem. A decorator usually aggregates something additional (add braids to the hair), instead of completely changing it, like you're trying to do with the skin (hair to scales).
A Builder pattern, (whereby you specify how you want the object built) may fit the problem better. In your case, you want to build a rabbit built with a reptile skin. (where Im from, instead of reptile skin, it would have been funny to make a rabbit with horns and call it a jackalope :)
I think the use of a Builder (or any pattern) here may actually be overkill. Do you absolutely have to use a pattern for this particular problem? How about just defining the code as follows and leave patterns out of it for now:
class Animal {
private $rest;
private $stomach;
private $skinType;
public function setSleep($hours) {
$this->rest = $hours;
}
public function setFood($food) {
$this->stomach = $food;
}
public function setSkinType($skin) {
$this->skinType = $skin;
}
// define the other getters too
public function getSkinType() {
return $this->$skinType;
}
}
class Rabbit extends Animal {
public function __construct() {
$this->rest = "rabbitRest"; // put whatever a rabbit rest is
$this->stomach = "rabbitStomach"; // put whatever a rabbit stomach is
$this->skinType = "hair";
}
}
Disclaimer: Im a c++ guy and my php is really bad, Im sure this code has several problems, but I hope you get the idea.
So a Rabbit would just extend an Animal and set its properties accordingly. Then if somebody wanted a RabbitReptile, they could either extend Rabbit (probably overkill) or just make a Rabbit and set the skin type accordingly.
I don't know if I fully understood your question. This is how I read it:
Your decorator is not yet complete. As it shows, it's still abstract and incomplete:
abstract class AnimalDecorator extends Animal {
protected $animal;
public function __construct(Animal $animal) {
$this->animal = $animal;
}
}
If you want to make it easily work, you should decorate all methods as well, so you don't need to do that when you extend from AnimalDecorator. Here exemplary for two of the many methods:
abstract class AnimalDecorator extends Animal {
...
public function getSkinColor() {
return $this->animal->getSkinColor();
}
public function setSleep($hours) {
$this->animal->setSleep($hours);
}
...
After you've delegated all methods, you can override the ones you want to in your concrete decorator as you already do:
class ReptileSkinDecorator extends AnimalDecorator {
public function getSkinColor() {
return "reptile";
}
}
The Decorator pattern must delegate all members defined in its base class or implemented interface to the object it is extending. In other words the ReptileSkinDecorator's setSleep, setEat, and getSkinType methods must call the Rabbit's (or whatever other Animal descendant you choose to decorate with reptile skin) setSleep and setEat methods.
Also, I just noticed that in your example you are trying to alter the use of a method defined in the Animal base class (trying to define a skin type, which I assume you want to be immutable). You shouldn't really do that (hide object's immutable properties) with a Decorator pattern, because if the object were to be available outside of the scope of the decorator it would provide a different skin type (as you've defined it). Decorators don't generally change existing properties of the object they're decorating.
Perhaps a better example would be a HibernationDecorator. Since your base class has nothing related to hibernation you may want to make that decorator so that you can provide hibernation functionality for your rabbit. That is what Decorator is about - providing additional functionality not present in the base class or interface contract while still adhering to the base class' contract.
I am studying the differences between Abstract and Interface and I read some sentence
saying
A child class can only extend a single abstract (or any other) class,
whereas an interface can extend or a class can implement multiple
other interfaces.
I understand when he says, “A child class can only extend a single abstract (or any other) class,” he means:
class first
{
public function Search()
{
return 'Hellow';
}
}
abstract class first2 extends first
{
}
class second extends first2
{
}
$ob = new second();
echo $ob->Search();
However, I didn’t understand the rest of his sentence, where he says, “whereas an interface can extend or a class can implement multiple other interfaces.”
Could someone please explain his last sentence and add a code example?
Thank you all and have a nice day.
You can implement more than one interface
interface C {
public function method1();
}
interface D {
public function method2();
}
class A implements C,D {
//implement from interface C
public function method1() {
}
//implement from interface D
public function method2() {
}
}
Here you will need implement methods from interface C and D. You can also extend interfaces within interfaces, like normal classes.
interface D extends C{}
It's useful when well you need some common methods. so you write "schema" into interface what methods you are expecting from base class to be implemented.
While abstract is single extended class, you canot create instance for it, only extend. It's useful when you want have some base class with common functionality or abstract methods what should be implemented later.
More you can always read at php.net - interfaces