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.
Related
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.
I have a set of read-only tests and a couple of ones that modify data (insert/update/delete). I'd like to back up my tables, so each test class would have a list of associated tables that they'll modify. This is just test data.
I thus thought of this:
abstract class DataAlteringTestBase extends PHPUnit_Framework_TestCase
{
protected function setUp()
{
echo "backing up tables: " . $this->GetAlteredTableNames();
}
public abstract function GetAlteredTaleNames();
}
One of the subclasses:
class DataAlteringTest extends DataAlteringTestBase
{
function GetAlteredTaleNames()
{
return array("some_table");
}
public function testDummyStuffChild()
{
$this->assertTrue(true);
}
}
The problem is, I think, that PHPUnit tries to get the method implementation from the abstract class, rather than its children.
Call to undefined method DataAlteringTest::GetAlteredTableNames() -
the implementation ...\tests\DataAlteringTestBase.php:6 - the abstract
class
How to fix it? or is there something wrong with the idea of implementing this in PHP/PHPUnit in the first place?
You have a few typos - you wrote GetAlteredTaleNames() in some places and GetAlteredTableNames() in other places.
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'm writing a power plugin for wordpress that basically supplies a bunch of functions to make development easier.
Don't worry about the wp stuff though, this is a PHP question. I have one master class 'my_wp_funcs', and a few other large classes that do different things, which I've written separately and work on their own, for example: insert a new post.
I would like to be able to use this syntax:
$wpfuncs = new funcs;
$wpfuncs->createpost($args);
$wpfuncs->addimage();
where createpost class extends funcs class, along with other classes that extend funcs too.
I've been reading up on abstraction, but am getting continual errors. Here's a trimmer version of what I have:
<?php
$wpfuncs = new funcs;
$wpfuncs->createpost($args);
abstract class funcs
{
abstract protected function createpost();
public function createpost($args){
$tool = new $this->boss_posttype('derp', 'derps');
}
}
class createpost extends funcs{
public function __construct(){
//do stuff
}
}
Cheers for any help!
You can't define the method as abstract in the abstract class and then define it for real in the same class. You also can't call the abstract class directly.
You probably want something like this:
abstract class funcs
{
abstract public function createpost($args);
}
class myFuncs {
public function createpost($args){
$tool = new $this->boss_posttype('derp', 'derps');
// do other stuff
}
}
$wpfuncs = new myFuncs();
$wpfuncs->createpost($args);
Note that your implementation goes in your own class, and that implementation has to match your abstract definition. (they both have to be public and they have to accept the same arguments)
Basically I'm looking for feedback or guidance on something I've created this week at work. The problem was that I had two types of document upload. These types both shared methods like upload, isUploaded, move etc. But, in some instances they both had unique functionality.
So I thought the best approach to handle this would be to create an abstract class which contains the common functionality and 2 separate classes which extend the base abstract class in order to inherit the common functionality.
So I have:
abstract class Upload {
protected $_id;
protected $_name;
protected $_dbTable;
abstract public function create(Filter $filter) {}
abstract public function update(Filter $filter) {}
public function __construct($id){
if(!is_null($id)){
$class = new get_called_class();
return new $class($id);
}
}
protected function upload(){
//Code implemented
}
protected function isUploaded(){
//Code implemented
}
protected function move(){
//Code implemented
}
}
Class Book_Upload extends Upload {
$dbTable = 'book';
public function __construct($id){
//Database stuff to obtain record information
//Set protected member variables
$results = $databaseCall();
$this->_id = $results['id'];
$this->_name = $results['name'];
}
public function create(Filter $filter) {
//Code implemented
}
public function update(Filter $filter) {
//Code implemenetd
}
//Other unique functions
}
Class Magazine_Upload extends Upload {
$dbTable = 'magazine';
Same as Booking_Upload but with additional functionality
plus abstract methods
}
My query is, am I using abstract methods correctly? Have I followed the correct path. Also, I'm not sure I need the construct in the abstract class. What if someone attempts to call $upload = new Upload($id)?
Any class should provide a single type of functionality (Single Responsibility Principle, example: Single Responsibility Principle - A hard to see example?).
An upload class must only deal with uploads. Without more code, I smell an over-functional class from your words that tries to accomplish both the upload and document-spesific tasks.
So before going that way, you should define well what these classes will be doing. Are those document-spesific functionalities really related to the actual act of uploading?
You're extending class doesn't call parent::__construct() so the abstract __construct won't make any difference.
You are using abstract classes correctly; they are base classes that are to be built upon by other classes that share common functions and/or will have the same functionality but is implemented differently.
Abstract classes are a base to be built upon that provide common functionality and structure to other classes.