diff --git a/1.md b/1.md index d9d46ba..e0aa964 100644 --- a/1.md +++ b/1.md @@ -109,7 +109,8 @@ $person->sayName(); //Joe Bob ##### Notes: -Objects are always passed by reference (rather than making a copy of it), meaning that a function that accepts an object as a parameter can modify the original object passed to it. +Objects are always passed by reference (rather than making a copy of it), meaning that a function +that accepts an object as a parameter can modify the original object passed to it. ## Coding Standards: diff --git a/3.md b/3.md index 2a4e905..de769c8 100644 --- a/3.md +++ b/3.md @@ -1,4 +1,4 @@ -# Lesson 3: Constructors +# Lesson 3: Constructors and Type Hinting ## New Keywords: - `__construct` @@ -81,7 +81,9 @@ class Person { ### Exercise: - 1 Using the class from Exercise 2, create a constructor function that takes + 1 Using the class from Lesson 2, create a constructor function that takes a $name parameter and assigns that value to the name property. - 2. Add 'height' and 'haircolor' to your constructor. + 2. Add 'height' and 'height' to your constructor. + + 3. Make use of type hints in the arguments to the methods. diff --git a/4.md b/4.md index 1c5ec0c..f9d6389 100644 --- a/4.md +++ b/4.md @@ -90,3 +90,4 @@ $url = Url::fromUserInput('/robots.txt'); ### Exercise: 1. Add a static method to the "Person" class that compares two individuals by age and returns the oldest one. + 2. Call that static method. diff --git a/5.md b/5.md index 1d1b4f4..c212b05 100644 --- a/5.md +++ b/5.md @@ -51,7 +51,7 @@ class Node extends ContentEntityBase { ``` -###Protected: visibility +### Protected: visibility Another level of visibility (information hiding) is "protected", which means that a protected property or method can be accessed only from within the class defining it, or any subclassses. In contrast, a private property/method is only @@ -100,3 +100,10 @@ echo $b->private; // Fatal error $b->testVisibilityA(); // Public, Protected, Private $b->testVisibilityB(); // Fatal error: subclass can't access $this->private ``` + +## Exercises: + + - Add a method "sayHi()" to the Person class. + - Create two sub-classes "Developer" and "Designer" that extend the Person class. + - Add a method "work()" to each of those subclasses. + - Use "parent" in a sub-class method. diff --git a/6.md b/6.md index 9469dcf..fbf10af 100644 --- a/6.md +++ b/6.md @@ -126,9 +126,15 @@ class Select extends Query { } ``` +## `final` + +The `final` keyword prevents child classes from overriding a method by prefixing the definition +with final. If the class itself is being defined final then it cannot be extended. + ## Exercise: - - Create an abstract class out of the Person class from lesson 2. - - Create a concrete class that extends the abstract class. - - Instantiate an object from the concrete class. - - Set the name of the person object, and then echo it back out. + - Convert the Person class into an abstract class. + - Convert into concrete classes the Developer and Designer classes. + - Instantiate objects from the concrete classes. + - Call some methods on those objects to see how they behave. + - Try instantiating an object of the abstract class to look at the PHP error. diff --git a/7.md b/7.md index 9e2fe05..e9e1bee 100644 --- a/7.md +++ b/7.md @@ -99,7 +99,8 @@ and provide a consistent API for module developers. ## Exercise: - - Create an interface to give a Person object from lesson 3 an email address and website. - - Modify the concrete class from lesson 3 to implement your new interface. - - Instantiate an object from the concrete class. - - Set the email and website of the object, and then echo it back out. + - Create a person interface that declares the methods "work()" and "sayHi()". + - Modify the abstract class Person so it implements that interface. + - Instantiate an object from a concrete class. + - Review what errors does PHP give when a method declared in the interface is missing on the + implementing class. diff --git a/9.md b/9.md index 3c5344f..58b1439 100644 --- a/9.md +++ b/9.md @@ -36,7 +36,7 @@ namespace ChapterThree\OOTraining; class Person { public function __construct($filename) { - $array = \Symfony\Component\Yaml\Yaml::parse(file_get_contents($filename)); + $array = \Symfony\Component\Yaml::parse(file_get_contents($filename)); // ... Do something else. } } @@ -49,7 +49,7 @@ Or by declaring the `use` keyword and adding the namespace to the top of the cla namespace ChapterThree\OOTraining; -use Symfony\Component\Yaml\Yaml; +use Symfony\Component\Yaml; class Person { public function __construct($filename) { @@ -58,18 +58,20 @@ class Person { } } ``` -### Use as +### Use `as` + +You can also create *aliases* to refer to the classes using `as`: ```php name = 'frank'; - $cat->meow = function() { - echo 'meow'; - }; - return $cat; +class Person { + + public $name; + public $age; + + function getName() { + return $this->name; + } + + function getAge() { + return $this->age; + } + } -$cat1 = cat(); -unset($cat1->name); -var_dump($cat1->name); -call_user_func($cat1->meow); +$person = new Person(); +$person->name = 'Arlina'; +$person->age = 32; + +var_dump($person); diff --git a/code_samples/2.php b/code_samples/2.php index f035288..f5ee5c2 100644 --- a/code_samples/2.php +++ b/code_samples/2.php @@ -1,13 +1,12 @@ name = $name; - } + private $name; + private $age; + private $height; - function setName($name) { + public function setName($name) { $this->name = $name; } @@ -15,8 +14,27 @@ public function getName() { return $this->name; } + public function setAge($age) { + $this->age = $age; + } + + public function getAge() { + return $this->age; + } + + public function setHeight($height) { + $this->height = $height; + } + + public function getHeight() { + return $this->height; + } + } -$person = new Person('asdf'); -$person->setName('ryryr'); -var_dump($person->getName()); +$person = new Person(); +$person->setName('Arlina'); +$person->setAge(32); +$person->setHeight(160); + +var_dump($person); diff --git a/code_samples/3.php b/code_samples/3.php index 4960c67..6cc758d 100644 --- a/code_samples/3.php +++ b/code_samples/3.php @@ -1,13 +1,45 @@ name = 'frank'; - $person->talk = function() { - echo 'hi'; - }; - return $person; +class Person { + + private $name; + private $age; + private $height; + private $birth_year; + + public function __construct(string $name = 'Anonymous', int $age = NULL, float $height = NULL) { + $this->name = $name; + $this->age = $age; + $this->height = $height; + $this->birth_year = date('Y') - $this->age; + } + + public function setName(string $name) { + $this->name = $name; + } + + public function getName() { + return $this->name; + } + + public function setAge(int $age) { + $this->age = $age; + } + + public function getAge() { + return $this->age; + } + + public function setHeight(float $height) { + $this->height = $height; + } + + public function getHeight() { + return $this->height; + } + } -$person = Person(); -var_dump(is_a($person, 'stdClass')); +$person = new Person('Arlina', 32, 160); + +var_dump($person); diff --git a/code_samples/4.php b/code_samples/4.php new file mode 100644 index 0000000..13b0fcb --- /dev/null +++ b/code_samples/4.php @@ -0,0 +1,53 @@ +name = $name; + $this->age = $age; + } + + public function setName(string $name) { + $this->name = $name; + } + + public function getName() { + return $this->name; + } + + public function setAge(int $age) { + $this->age = $age; + } + + public function getAge() { + return $this->age; + } + + /** + * Return the person who is older, or NULL if they have the same age. + * + * @param \Person $a + * @param \Person $b + * + * @return null|\Person + */ + public static function returnWhoIsOlder(Person $a, Person $b) { + if ($a->getAge() > $b->getAge()) { + return $a; + } + elseif ($b->getAge() > $a->getAge()) { + return $b; + } + + return NULL; + } + +} + +$personA = new Person('Arlina', 32); +$personB = new Person('Methuselah', 969); +$oldest = Person::returnWhoIsOlder($personA, $personB); +echo $oldest->getName() . ' is older'; diff --git a/code_samples/5.php b/code_samples/5.php index 4068d8d..815b384 100644 --- a/code_samples/5.php +++ b/code_samples/5.php @@ -1,30 +1,51 @@ name; + } + + public function setName(string $name) { + $this->name = $name; + } public function sayHi() { - echo "hi" . PHP_EOL; + echo "Hi"; } } -class CPerson extends APerson { - private $name; +class Developer extends Person { - function getName() { - return $this->name; + public function work() { + echo 'Coding!' . PHP_EOL; } - function __construct() { - $this->sayHi(); + public function sayHi() { + parent::sayHi(); + echo "I'm a developer." . PHP_EOL; } - function setName($name) { - $this->name = $name; +} + +class Designer extends Person { + + public function work() { + echo 'Designing!' . PHP_EOL; } + + public function sayHi() { + parent::sayHi(); + echo "I'm a designer." . PHP_EOL; + } + } -$person = new CPerson(); -$person->setName('Alice'); -echo $person->getName(); +$programmer = new Developer(); +$programmer->sayHi(); // Hi I'm a developer. +$programmer->work(); // Coding! + +$designer = new Designer(); +$designer->sayHi(); // Hi I'm a designer. +$designer->work(); // Designing! diff --git a/code_samples/6.php b/code_samples/6.php new file mode 100644 index 0000000..f4b3a86 --- /dev/null +++ b/code_samples/6.php @@ -0,0 +1,53 @@ +name; + } + + public function setName(string $name) { + $this->name = $name; + } + + public function sayHi() { + echo "Hi"; + } +} + +class Developer extends APerson { + + public function work() { + echo 'Coding!' . PHP_EOL; + } + + public function sayHi() { + parent::sayHi(); + echo "I'm a developer." . PHP_EOL; + } + +} + +class Designer extends APerson { + + public function work() { + echo 'Designing!' . PHP_EOL; + } + + public function sayHi() { + parent::sayHi(); + echo "I'm a designer." . PHP_EOL; + } + +} + +//$person = new APerson(); // Error! + +$programmer = new Developer(); +$programmer->sayHi(); // Hi +$programmer->work(); // Coding! + +$designer = new Designer(); +$designer->sayHi(); // Hi +$designer->work(); // Designing! diff --git a/code_samples/7.php b/code_samples/7.php index 6dcafcf..c285a79 100644 --- a/code_samples/7.php +++ b/code_samples/7.php @@ -1,38 +1,64 @@ name; + } - function getName() { - return $this->name . ' Basic'; + public function setName(string $name) { + $this->name = $name; } + + public function sayHi() { + echo "Hi"; + } + + abstract public function work(); } -class AdvPerson implements IPerson { - private $name=IPerson::NAME; +class Developer extends APerson { - function getName() { - return $this->name . ' Advanced'; + public function work() { + echo 'Coding!' . PHP_EOL; } + + public function sayHi() { + parent::sayHi(); + echo "I'm a developer." . PHP_EOL; + } + } -class Client { - function __construct() { - $basic = new BasicPerson(); - $adv = new AdvPerson(); - $this->sayHi($basic); - $this->sayHi($adv); +class Designer extends APerson { + + public function work() { + echo 'Designing!' . PHP_EOL; } - // Important type hinting, note that we're using the interface as the type. - function sayHi(IPerson $person) { - echo "Hi " . $person->getName() . PHP_EOL; + public function sayHi() { + parent::sayHi(); + echo "I'm a designer." . PHP_EOL; } + } -$worker = new Client(); +//$person = new APerson(); // Error! + +$programmer = new Developer(); +$programmer->sayHi(); // Hi +$programmer->work(); // Coding! + +$designer = new Designer(); +$designer->sayHi(); // Hi +$designer->work(); // Designing!