Welcome to my series on every PHP keyword and its usage. Today’s item: abstract.

The abstract keyword can be used to enforce that a class or method cannot be used directly, but must be extended. An abstract method can only be used inside of an abstract class.

When a class is marked abstract, it must be extended. When a method is marked abstract, it must be overridden with the same signature. In this way, it is similar to an interface.

The primary difference between an abstract class and an interface, is that an abstract class can have concrete methods and properties, as well as abstract methods.

If you can choose between an interface and an abstract class, always choose an interface. Any class can implement an interface, while only a class with no parent can extend an abstract method.

Note:

  • An abstract class can extend a concrete class.
  • A property cannot be marked abstract.
  • Both normal and static methods can be marked abstract.

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
abstract class Asset
{
	private $path = "";
	private $minifiedPath = null;
	
	public function __construct($path)
	{
		$this->path = $path;
	}
	
	public function getPath()
	{
		return $this->path;
	}
	
	// Abstract methods have no body, and have a semicolon at the end
	protected abstract function minify(string $path): string;
	
	public function getMinifiedPath()
	{
		if($this->minifiedPath === null)
		{
			$this->minifiedPath = $this->minify($this->path);
		}
		
		return $this->minifiedPath;
	}
}

class Script extends Asset
{
	// Extended methods must have the same name, argument types and return
	// type. Arguments can have different names, though.
	protected function minify(string $javascriptPath): string
	{
		return JavascriptMinifier::minify($javascriptPath);
	}
}

class Styles extends Asset
{
	// You can add more arguments when extending an abstract method, but they
	// must have default values
	protected function minify(string $path, bool $simplify = true): string
	{
		return CssMinifier::minify($path, $simplify);
	}
}

Traits

Traits can also have abstract methods. An abstract method within a trait must be implemented by the class that uses that trait.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php
trait NameComparable
{	
	public static function compareNames(self $first, self $second): int
	{
		return $first->getName() <=> $second->getName();
	}
	
	public abstract function getName(): string;
}