I'd like to develop an abstract class to be extended to fit custom requirements. Most of the methods will be fully implemented in this base class. However, it will rely heavily on the values set in the members, which the child class should define. The reason I'm saying "abstract" class is that I want to force the extenders of the class to define values for the members. Is this possible?
I know I can define methods to be abstract and force extenders to implement those. I'm not sure about members. Furthermore, is this good design practice?
Example:
abstract class foo_bar
{
// I want child class to define these
private $member1 = 0;
private $member2 = 0;
private $member3 = 0;
// Child class and instances can access this
public function foo()
{
return 'foo';
}
// Child class must implement this
abstract function bar();
}
In short: No. There's no such thing as abstract properties in PHP.
You may as well just declare those properties as protected in the abstract class itself so the child inherits them. Even if you'd declare them abstract, there's no guarantee the child implements them with useful values, so it has about the same effect.
Related
Went over a thing like this and I don't know
abstract class Foo {
abstract private function test();
}
Is this a nonsense or NOT?
If not please explain why.
if you speak about private range inside you abstract class, no it is not a nonsence
Since an abstract class can contain functionality (as opposed to an interface) it can have private variables or methods.
I will give you this link with a great answer (even it is in java, it is the same with php) Why is there a private access modifier in an abstract class in Java, even though we cannot create an instance of an abstract class?
Abstract methods cannot be private, because by definition they must be implemented by a derived class. If you don't want it to be public, it needs to be protected, which means that it can be seen by derived classes, but nobody else.
The PHP manual on abstract classes shows you examples of using protected in this way.
http://php.net/manual/en/language.oop5.abstract.php
It makes sense if you want to make that method inaccessible further down in the inheritance chain, e.g. grandchildren of that abstract class. For example:
abstract class Foo {
abstract private function test();
}
class FooChild extends Foo {
private function test()
{
// Here you implement the body of the method
}
public function bar()
{
$this->test(); // This will work
// Do something else
}
}
class FooGrandChild extends FooChild {
}
$grandchild = new FooGrandChild();
$grandchild->test(); // This will throw an exception
In my abstract class My_Class, I have a method My_Class::foo() that's called from within another method belonging to the class. For example:
abstract class My_Class {
function foo() {
// Stuff.
}
function bar() {
$this->foo();
}
// More methods etc...
}
Now, I'm in the process of extending my abstract class. For example:
class My_Class_Extended extends My_Class {
}
As you'll know, both My_Class::foo() and My_Class::bar() are inherited by My_Class_Extended.
I never want My_Class::foo() to be called outside of My_Class or My_Class_Extended so I know not to make its visibility public. My problem is, I'm unsure whether to make its visibility protected or private.
My question
Considering how I'm calling My_Class::foo() in the above scenario, should it be made protected or private? I'm not sure if the call to My_Class::foo() is coming from the child or parent class.
Thanks in advance.
One-line: protected, because you want your child classes have access
The visibility modifiers work like this:
public: visible from everywhere.
$c = new My_Class_Extended(); $c->thisIsPublic();. This doesn't work with private or protected
protected: visible inside of the class and it's child classes
You can only call these functions inside of a function belonging to a class that derives from your parent class, or the parent class itself.
private: Only visible for the class it's defined in. You cannot call private functions in child classes, nor outside of the class.
The modifiers are ordered inclusively. So a protected is more restrictive than public, and private is more restrictive than protected.
You want protected, because you want to call them inside a child class, but not outside of it.
By the way: In your context, the abstract keyword only ensures that you cannot create an instance from My_Class.
I'm trying to learn OOP in PHP, for now i have reached the abstract classes.
I have some problems understanding when should I implement abstract methods in the abstract class and when I should not.
For example, have this code:
<?php
abstract class concept_car {
/**
* Properties can not be declared as abstract natively:
* http://stackoverflow.com/questions/7634970/php-abstract-properties
*/
protected $weelNum = NULL;
protected $doorsNum = NULL;
protected $color = NULL;
protected $carType = NULL;
// the inheritance class must define this methods
abstract public function setWeelNum($weelNum);
abstract public function setDoorsNum($doorsNum);
abstract public function setCarType($carType);
}
I do not know if it is OK to declare the 3 methods as abstract or should I remove the abstract and implement them because the properties are in the same class as the methods.
In the actual form of the code I was thinking that I must declare the methods as abstract here and implement them in the inheritance class, in the child class, but I don't know if this is the correct way.
P.S: I am a beginner and I am trying to understand how things go, I didn't reach at design patterns yet so please explain me in concepts so i can know what is the right way to proceed.
Simple question you have to ask yourself:
Do all classes that extend this one do the same thing?
For this example, the answer is yes, they will all do
public function setWeelNum($weelNum) {
$this->weelNum = $weelNum;
}
So don't copy/paste that code in each class, it's no point.
When should you declare an abstract method ?
When all the children of that class must implement this method but in different ways.
For example, in the class Animal, you will have a public abstract function move(); because all animals move, but you don't know how exactly.
Generally, you should implement all methods in the last common ancestor. So if you want your children classes will behave the same way, implement them now. If they are to be implemented, but in many ways by different classes, leave them abstract.
Actually, an abstract class is done only for requiring that if somebody will inherit something from this common class, he will provide these methods (abstract class is something similar to interface).
If you implement all of them, there is no need to use an abstract class.
Let's say I have 2 classes
class BaseClass {
...
}
class SomeClass extends BaseClass {
}
now I want to create third class, that will only extend SomeClass, but not get anything from BaseClass. Is that even possible?
I'm writing Selenium tests with webdriver and want to check data from Selenium against DB or WebServices, but don't want to load the whole framework, just some of our libraries
You can't. That's not how Inheritance works. A class inheriting from SomeClass will always inherit all it's properties and methods, including those of SomeClass inherited from BaseClass. You can limit access to them through Visibility, but only from private over protected to public, not the other way round, e.g. you can loose visibility, but not tighten it.
See the chapters in the PHP Manual about Inheritance and Visibility:
http://php.net/manual/en/language.oop5.inheritance.php
http://php.net/manual/en/language.oop5.visibility.php
Another option would be to use some sort of Facade around an instance of SomeClass to control the access to properties and methods accessible in SomeClass, e.g. assuming your SomeClass has a method foo() and inherits bar() from BaseClass, you could do
class LimitedAccess
{
private $instance;
public function __construct(SomeClass $someClass)
{
$this->instance = $someClass
}
public function foo()
{
return $this->instance->foo;
}
}
and then you can funnel all access through this Facade effectively preventing access to BaseClass::bar(). Note, that this will not change the inheritance hierarchy in any way. It just controls access.
Think about as Human...
You have mother and she has mother...
You cant be son of your mother without being grandson of your grandmother..
same is at PHP
when Class extends other its AWAYS his child...
You can definitely do that if you put a PROTECTED access modifier on the method in BaseClass that you want to be restricted to be called from the Third class..
I have been tinkering around with OOP and seeing how to go about doing this. I have parent class that does stuff and sets values to its own properties. Then I want to create a child class that extends the parent while "somehow" accessing the dynamically modified properties. I was wondering if this could be done with a proxy of some sort. Im still learning so i'm not 100% sure on the OOP strategies here.
class Parent
{
public $test;
public function boot()
{
// boot stuff
$this->internalStuff();
}
public function internalStuff()
{
$this->test = 'World!';
$c = new Child();
$c->cTest();
}
}
$p = new Parent;
$p->boot();
class Child extends Parent
{
public function __construct()
{}
public function cTest()
{
echo 'Hello ' . $this->test;
}
}
Inheritance (parent/child relationships between classes) only extends to the class definition. I.e. what methods and properties a class has. It only defines the "blueprint" of a class. The actual values are assigned to object instances of the class. You cannot modify the inheritance of an instantiated object. Neither does one object magically take over the values of another object, regardless of how their parent/child relationship is.
So no, it just doesn't work that way. If you want a Child object to have certain values, you need to assign them to an instance of that object. Whatever you did with a completely different object instance of another class doesn't matter.