Inheritance: Vertical
or Horizontal?
Mark Niebergall

https://joind.in/talk/77415
About Mark Niebergall
• PHP since 2005
• Masters degree in MIS
• Senior Software Engineer
• Drug screening project
• UPHPU President
• CSSLP, SSCP Certified and SME
• Drones, fishing, skiing, father, husband
About Mark Niebergall
• Twitter @mbniebergall
• phpug.slack.com
• phpchat.slack.com
• phpcommunity.slack.com
• utos.slack.com
Inheritance: Vertical or
Horizontal?
Inheritance: Vertical or
Horizontal?
• Objective

- Solid understanding of how inheritance works in PHP

- Know when and how to use inheritance in PHP

- Able to apply material to current projects
Inheritance: Vertical or
Horizontal?
• The Problem

• Vertical inheritance

• Horizontal inheritance

• Applied use

• Considerations
The Problem
The Problem
• Copy and paste
The Problem
• Procedural code

- Simple

- Efficient
The Problem
• Procedural code

- Lacks organization

- Difficult to scale
The Problem
• Functions

- Reusable

- Some organization

- No grouping
The Problem
• Concrete Class

- Basic code organization with classes

- Concrete class can be instantiated
The Problem
• Concrete Class

- Properties

- Constants

- Methods

- Magic methods
The Problem
• Concrete Class

- class X {

const SOME_THING = ‘Thing’;

protected $flag = true;

private function secretStuff() {…}

public function doSomething() {…}

}
The Problem
• Concrete Class

- Problems by themselves

‣ Code reuse, duplication

‣ Code enforcement

‣ Code organization
The Problem
• Concrete Class

- Problems by themselves

‣ Classes can become bloated

‣ No separation of services

‣ Complicated code
The Problem
• Concrete Class

- Problems by themselves

‣ Hard to debug

‣ Testability goes down
The Problem
• Concrete Class

- Some problems solved with Dependency Injection (DI)

‣ public function __construct(Dependency $d) {

$this->dependency = $d;

}

public function setThing(Thing $thing) {

$this->thing = $thing;

}

public function __set($key, $value) {

if ($value instanceof Thing) {$this->thing = $value;}

}
The Problem
• Concrete Class

- Problems solved with inheritance
The Problem
• Concrete Class

- Composition over Inheritance

- Inheritance over Composition
Vertical Inheritance
Vertical Inheritance
• Family

- Olsen line

‣ Stature

‣ Stubbornness

- Niebergall

‣ Engineering
Vertical Inheritance
• Service provider

- Education

‣ University

- Utilities

‣ Garbage collection
Vertical Inheritance
• Animal

- Pet

‣ Dog

• German Shepard

‣ Cat

• Short-hair
Vertical Inheritance
• Abstract

• Interface
Vertical Inheritance
• Abstract

- X is a Y
Vertical Inheritance
• Abstract

- X is a Y

‣ Mark is a Niebergall

‣ Garbage Collection is a Utility

‣ Cat is a Pet
Vertical Inheritance
• Abstract

- X is a Y

‣ Pet is an Animal

• Cat is a Pet

• Short-hair is a Cat
Vertical Inheritance
• Abstract

- abstract class Animal {…}

‣ abstract class Pet extends Animal {…}

• abstract class Cat extends Pet {…}

• class class ShortHair extends Cat {…}
Vertical Inheritance
• Abstract

- abstract class Animal {

abstract public function breathe(Lungs $lungs) : Lungs;

private function beAlive() : Animal {…}

}

abstract class Cat {

public function breathe(Lungs $lungs) : Lungs {…}

final protected function purr() {…}

}
Vertical Inheritance
• Abstract

- class ShortHair {

public function takeNap() {

$this->goToSleep();

}

public function getPetted() {

$this->purr();

}

}
Vertical Inheritance
• Abstract

- Extend only one class at a time

- Can have multiple levels of inheritance

- Can not instantiate abstract
Vertical Inheritance
• Abstract

- Abstract functions must be implemented

- Signatures must match
Vertical Inheritance
• Abstract

- Benefits

‣ Reduce code duplication

‣ Code organization

‣ Logical flow
Vertical Inheritance
• Abstract

- Push code up the vertical inheritance chain as far as it
logically makes sense
Vertical Inheritance
• Abstract

- Questions?
Vertical Inheritance
• Interface
Vertical Inheritance
• Interface

- interface X {

const SOME_VALUE = 123;

public function processThing(Thing $thing) : Thing;

}
Vertical Inheritance
• Interface

- Object interface
Vertical Inheritance
• Interface

- Connect two things together

‣ User interface

‣ Driver and vehicle

‣ Controller
Vertical Inheritance
• Interface

- Contract defining what needs to happen but not how

- Contract between concept and implementation
Vertical Inheritance
• Interface

- Define interaction requirements

- Leaves implementation to be handled in classes

- Can not be instantiated
Vertical Inheritance
• Interface

- Class can implement multiple interfaces

- Can be used with abstract and class

- Can not be used with a trait

‣ RFC in discussion about that
Vertical Inheritance
• Interface

- interface X {…}

- class A implements X {…}

- abstract class Z implements V, W, X {…}
Vertical Inheritance
• Interface

- Interface method signatures are defined

- No method content

- Method signature must match when implemented

- Methods must be implemented

- Interface can extend one or many interfaces
Vertical Inheritance
• Interface

- All methods must be public

- Properties are not allowed

- Can have public constants
Vertical Inheritance
• Interface

- Light from different sources

- interface LightInterface {

const LIGHT_SPEED = 299792458;

public function shine(Energy $energy) : Light;

public function travel(float $x, float $y, float $z);

}
Vertical Inheritance
• Interface

- Laptop computer

‣ USB

‣ Video and audio output

‣ Card reader
Vertical Inheritance
• Interface

- interface Power {

public function receivePower(Volt $v, Current $i);

}

interface Usb extends Power{

public function transferData(Data $data);

}

interface Hdmi {

public function transmitVideo(Video $video);

}

abstract class Laptop implements Usb, Hdmi {…}
Vertical Inheritance
• Interface

- Underwater pets

- Auditing

- Authentication methods

- Request and response

‣ Middleware
Vertical Inheritance
• Interface

- Questions?
Vertical Inheritance
Horizontal Inheritance
Horizontal Inheritance
• Personal characteristics

- Hair color

- Personality
Horizontal Inheritance
• Underwater creature

- Fish

- Mammal

- Reptile
Horizontal Inheritance
• Trait
Horizontal Inheritance
• Trait

- trait M {

protected $thing;

public function doThing(Thing $thing) : Thing {…}

}

class X {

use M;

protected function something(Thing $thing) : Thing {

return $this->doThing($this->thing($thing);

}

}
Horizontal Inheritance
• Trait

- Promotes code reuse

- Unrestricted by inheritance hierarchies

- Available since PHP 5.4.0
Horizontal Inheritance
• Trait

- Pull in grouped functionality

- Multiple inheritance horizontally

- Similar to a concrete class but cannot be instantiated
Horizontal Inheritance
• Trait

- “Aware” of a concept

‣ ContainerAware

‣ AuditAware

‣ AdapterAware
Horizontal Inheritance
• Trait

- Can be used alongside abstracts and interfaces in a class

- Class can use multiple traits

- Used in abstract class or concrete class

- Can have properties and methods
Horizontal Inheritance
• Trait

- Can not be instantiated

- Can not implement an interface

- Can not extend a class
Horizontal Inheritance
• Trait

- Methods and properties in trait(s) become available to
class

- Traits can not have class constants
Horizontal Inheritance
• Trait

- Order of precedence

‣ Class and trait method naming collisions

• Current class

• Trait

• Parent class
Horizontal Inheritance
• Trait

- abstract class TheBase {

public function hello() { echo ‘Hello from the base.’; }

}

trait TheTrait {

public function hello() { echo ‘Hello from the trait.’; }

}

class TheClass extends TheBase {

use TheTrait;

public function hello() { echo ‘Hello from the class.’; }

}
Horizontal Inheritance
• Trait

- trait TheTrait {

public function hello() { echo ‘Hello from the trait.’; }

}

class TheClass extends TheBase {

use TheTrait {

TheTrait::hello as helloTrait;

};

public function hello() { echo ‘Hello from the class.’; }

public function helloBase() { parent::hello(); }

}
Horizontal Inheritance
• Trait

- Naming conflicts must be resolved

‣ Fatal error if not
Horizontal Inheritance
• Trait

- ‘insteadof’ to use just one

- ‘as’ to alias and allow using more than one
Horizontal Inheritance
• Trait

- class Thing {

use TraitA, TraitB {

TraitA::doThing insteadof TraitB;

TraitA::doOtherThing as doOtherThingA;

TraitB::doOtherThing as doOtherThingB;

}

}

$thing->doThing();

$thing->doOtherThingA();

$thing->doOtherThingB();
Horizontal Inheritance
• Trait

- Can change visibility modifier

‣ use Trait { methodName as protected; }

‣ class Thing {

use Trait {

Trait::doThing as public;

}

}

$thing->doThing();
Horizontal Inheritance
• Trait

- Traits can have properties

- Class properties must match visibility and initial value if
same name

‣ trait X {

public $something = ‘something’;

}

class Z {

use X;

public $something = ‘something’;

}
Horizontal Inheritance
• Trait

- Traits can use other traits

‣ trait Thing {

use ThingA, ThingB;

}
Horizontal Inheritance
• Trait

- Traits can have abstract methods

‣ trait Thing {

abstract protected function doSomething();

}

class X {

use Thing;

protected function doSomething() {

echo ‘doing something’;

}

}
Horizontal Inheritance
• Trait

- Traits can have static methods

‣ trait Thing {

public static function anotherThing();

}



class X { use Thing; }



X::anotherThing();
Horizontal Inheritance
• Trait

- Recap

‣ Overcome multiple inheritance problem

‣ Horizontal inheritance
Horizontal Inheritance
Applied Use
Applied Use
• Vertical or Horizontal inheritance?

- Vertical: abstract, interface

- Horizontal: trait
Applied Use
• Vertical or Horizontal inheritance?

- Vertical is heavily used

- Most concrete classes extend an abstract in projects
Applied Use
• Vertical or Horizontal inheritance?

- My experience

‣ Most use vertical

‣ Few use horizontal
Applied Use
• Vertical or Horizontal inheritance?

- My experience with concrete classes

‣ Most extend an abstract

‣ Some implement an interface

‣ Few use trait
Considerations
Considerations
• Open discussion
Considerations
• Why need for abstracts, interfaces, and traits
Considerations
• Benefits of using combinations of abstracts, interfaces, and
traits
Considerations
• Traits vs Dependency Injection
Considerations
• Role of Dependency Injection
Considerations
• Code complexity

- How far to take abstraction

- Readability

- Code consolidation
Considerations
• Code testability

- Unit tests

- Testing abstract instead of concrete implementation
Considerations
• Evaluating current projects

- Static code analysis

- Leverage inheritance
Questions?
• Please rate this talk

- https://joind.in/talk/77415
Sources
• https://en.wikipedia.org/wiki/Convair_B-36_Peacemaker

• http://www.boeing.com/resources/boeingdotcom/commercial/737ng/assets/images/
marquee.jpg

• https://www.gannett-cdn.com

• http://pop.h-cdn.co/assets/15/20/1600x800/landscape-1431629947-marty-delorean.jpg

• http://www.sbs.com.au/movies/sites/sbs.com.au.film/files/styles/full/public/Dynamite_704.jpg?
itok=_XPK3CbV&mtime=1404453609

• http://latimesblogs.latimes.com/.a/6a00d8341c630a53ef01310f8dd9fe970c-pi

• https://i.pinimg.com/474x/f8/32/b4/f832b4c3b92cc4ccd19a285f68a4197a--merlin-olsen-little-
houses.jpg

• php.net

Inheritance: Vertical or Horizontal