Abstract class cannot be implemented? (PHP 5.2.9) - php

do I have something wrong in my code or I really cannot implement interface in the abstract class? My code is not working and PHP throws an error:
Fatal error: Class 'Blah' not found
My code:
interface IBlah {
public function Fun();
}
abstract class Blah implements IBlah {
public function FunCommon() {
/* CODE */
}
abstract public function Fun();
}
class Koko extends Blah {
public function Fun() {
/* CODE */
}
}
When I'll change my code to following, now it works:
abstract class Blah {
public function FunGeneral() {
/* CODE */
}
abstract public function Fun();
}
Am I doing anything wrong? Thank you very much.
EDIT: 2014-04-01
I'm sorry #raina77ow, I was too rash. Your answer is correct and it helped me very much - I understood interface x abstract class and your advice will be really helpful in the future (my +1 for you still remains), but I tried it on another machine. Today, when I came to work and I apply your advice, the error still showed up.
I'd like to give you additional information. At the first, I removed "abstract public function Fun();" from my abstract class according to your advice. The second thing is that my interface and abstract class are in one PHP file and class Koko is in another one (if I move class Koko into the same file as interface and abstract class, no error is thrown).
I tried to print declared interfaces - get_declared_interfaces(), and declared classes - get_declared_classes(), and interface IBlah is printed out, but nor Blah neither Koko are printed out.
And When I change declaration of abstract class implementing interface only to abstract class (as I described above), Iblah and Blah and Koko are printed out all of them.

There's no need declaring an abstract function in an abstract class that's already declared in the interface it implements - you'll get an error (in PHP 5.2, looks like PHP 5.3 treats it a bit differently):
Can't inherit abstract function IBlah::Fun() (previously declared
abstract in Blah)
Solution: just drop this declaration from an abstract class altogether - this...
interface IBlah {
public function Fun();
}
abstract class Blah implements IBlah {
public function FunCommon() {}
}
class Koko extends Blah {
public function Fun() {}
}
... is a valid code both in PHP 5.2 and PHP 5.3, and Koko objects will be treated as IBlah ones. That's easy to check:
function t(IBlah $blah) {
var_dump($blah);
}
t(new Koko()); // object(Koko)#1 (0) {}

Related

classes interaction methods php

Lets say we have class B which extends class A. When creating new instance of class B and providing value into it that value is used in constructor of class A. Please check sample below.
I'm little bit confused about such behavior. If method "display" do not pass value into class A it should not get there, or am i missing something?
class A {
protected $changeableString = 'initial value';
public function __construct($providedText)
{
$this->changeableString = $providedText;
}
public function printString(){
echo $this->changeableString;
}
}
class B extends A {
public function display(){
echo $this->changeableString;
}
}
$test = new B('provided value');
$test->display();
edit: I have changed function __construct from protected to public according comments. It is indeed gives error, so if someone will review this issue now code is correct.
First of all the topic you are talking about is called Inheritance in Object-Oriented Programming (OOP).
If class B has no construct (__construct) then PHP will call the construct of class A.
And about display function, think of it as an addition to everything in class A but will not be available in class A
So class B is like class A but has one more function called display.
Note:
As #Brian said, if you try to call new B('provided value') that will produce the following error:
Fatal error: Uncaught Error: Call to protected A::__construct() from global scope in ..
and to solve it just make the construct of class A public so class B.

Declaring abstract the method implemented from an interface

I wonder if it is possible to not implement a method coming from an interface and let child class do it.
For example :
abstract class Foo implements Bar
{
public abstract methodFromBar();
}
And then :
class SubFoo extends Foo
{
public methodFromBar()
{
// Implementation...
}
}
The idea behind this is to simplify development and just specifying that the subclass extends from the main class instead of writing again that the subclass implements the interface.
You don't need to mention the interface method in the parent class at all. If it doesn't implement the interfaces listed, then PHP will require that the subclass fulfills the contract instead. This will work fine:
interface Bar
{
public function methodFromBar();
}
abstract class Foo implements Bar
{
}
class SubFoo extends Foo
{
public function methodFromBar()
{
echo 'Hello world';
}
}
$subFoo = (new SubFoo)->methodFromBar();
// Hello world
See https://eval.in/1016337
If the subclass does not implement the method, you'll receive a message along the lines of
Fatal error: Class SubFoo contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Bar::methodFromBar)
Whether or not you think it's a good idea for an abstract class to implement an interface is probably a discussion for another site.

Multi-level inheritance in PHP classes

Lets say I have this code:
class A {
...
}
class B extends A {
...
}
class C extends B {
...
}
$c = new C();
$c->getMethodOrPropertyFromB()->getMethodOrPropertyFromA();
Other than a bad architecture or bad design will this have any impact on PHP / Webserver (Apache/Nginx) performance when the script executes?
If this is not recommended to have such multi-level in PHP classes, can you explain why?
Note: in addition to the answers I've got I will let this here which is helpful as well
My initial thought was that this may not be good for inheritance but after testing it seems okay. However, there are other means of accomplishing this you could be aware of.
Abstract classes or Interfaces may make sense.
Abstract classes are just like other classes but they cannot be instantiated. There are also abstract methods which must be implemented by concrete classes.
abstract class A {
//You can also have abstract methods
abstract public function doFoo();
abstract public function doBar($when);
//Also implemented method which when
//called unless overridden will use this logic
public function sayHi(){
echo "hi";
}
}
Now this class can choose to implement the abstract methods or not also adding any further logic needed by it.
abstract class B extends A {
public function doFoo(){
//Some code
}
abstract public function doFooBar();
public function sayBye(){
echo "bye";
}
}
This is a concrete class and all abstract methods must be implemented here if not already ones that are implemented can be overridden yet again.
class C extends B {
public function doFoo(){
//Some different code
}
public function doBar($when){
//Some code
}
public function doFooBar(){
//Some code
}
//do not need sayHi() and sayBye() but they will be available.
}
Interface in a simple and crude way is a bag of methods. You are simply telling the developer if you are going to use this implement these. These methods are not declared as abstract but cannot be implemented in the interface.
interface iA {
public function doFoo();
public function doBar();
}
An interface can be extended by other interface which is just adding more methods to the interface
interface iB extends iA {
public function doFooBar();
}
interface iC {
public function doAnything();
}
And implemented by classes
class A implements iA{
public function doFoo(){
//Some Code
}
public function doBar(){
//Some Code
}
}
class B implements iB{
public function doFoo(){
//Some Code
}
public function doBar(){
//Some Code
}
public function doFooBar(){
//Some Code
}
}
The added advantage of interfaces is that a class or abstract can implement more then one
abstract class C implements iA, iC {
public function doFoo(){
//Some Code
}
}
class D extends C {
//get doFoo() from C implementation and must implement the remaining...
public function doBar(){
//Some Code
}
public function doAnything(){
//Some Code
}
}
This seems perfectly fine. PHP only support single inheritance - so you can only inherit from one class.
If you need more functionality in a class but cannot get the functality in a parent class you can also consider using traits. Traits try to solve the single inheritance problem - even if it's not a problem per se.
If you properly build your classes you get a nice chain of inheritance which does not have any bad influences onto Apache/Nginx.

Is it compulsory to declare abstract class for abstract method?

I have a below program
<?php
abstract class foo
{
abstract public function callme();
public function testing()
{
return $this->callme();
}
}
class bar extends foo
{
public function callme()
{
return "hello";
}
}
$objBar = new bar();
echo $objBar->testing();
?>
I defined abstract class foo. Is it compulsory to write abstract before class ? Because if i removed abstract i am getting fatal error.
Yes, if it contains abstract methods.
By declaring a method as abstract you are saying that in order to use this class, extending classes must implement the abstract method.
Your foo class cannot be instantiated unless callme is implemented, hence it must be declared abstract.
These concepts are perhaps better explained with a real world example than your standard abstract class Vehicle, class Car extends Vehicle tutorials.
Let's say we have a reporting system that does some querying on the database.
We find that all reports must be implemented in a standard way to share code and help with future maintenance.
So we define:
abstract class Report
{
}
For the sake of argument, all of our reports require a database connection.
abstract class Report
{
/** #var PDO */
protected $dbh;
public function __construct (PDO $dbh)
{
$this->dbh = $dbh;
}
/**
* #return array
*/
abstract public function getData();
}
Here we have also decided that all of our reports must implement a public getData method that returns an array.
This means:
We can ensure all our reports have a database connection
We can instantiate and then run each report in the same way
The abstract class definition has enforced the way we consume this code and makes sure that every type of report, regardless of which developer on your team wrote it, conforms to the convention we have decided.
Other code is then able to select a report from user input, run it, and do something with the result of getData (such as writing it to a CSV file) knowing that it will be an array.

Access to inherited children's variables of abstract class from another children of same abstract class

So, I have folowing problem:
I have abstract class with multiple children of this abstract class.
In my opinion, the best explanation is an example:
abstract class AbstractClass
{
public $varialbe = false;
abstract function process();
}
class Child1 extends AbstractClass
{
public function process()
{
//some code here
}
}
class Child2 extends AbstractClass
{
public function process()
{
//!!!Problem is here = Fatal error: Cannot instantiate abstract class AbstractClass
$child1 = new Child1();
//I need something like this:
$child1->varialbe = $this->variable;
$child1->process();
}
}
$child2 = new Child2();
$child2->process();
Thanks for help!
Your code works for me! I do not get a fatal error.
The only thing I get is a notice because of the typo inside $this->variable in the child2 class. The original variable is incorrectly spelled "varialbe", but used consistently.
Fixing the typo lets the code run completely error-free.
So you fail to demonstrate the problem. Update your question if you find why the issue isn't included in your code. It must be somewhere else.
And make sure you actually run your code before using it as an example, and that it has the problem you describe.

Categories