Основы ООП. Наследование
Краткое содержание лекции
Теоретические задания |
Практические задания
С наследованием мы частично столкнулись при изучении синтаксиса создания классов.
При условии, что такое наследование вам известно, мы начнем сразу с практики.
Хороший код сразу написать трудно, также трудно учесть всевозможные ситуации, пожалуй, даже неправильно учитывать того, чего не существует.
Пишите код для того, что вам действительно нужно.
Если у вас есть группа объектов, которые имеют общие свойства, методы, возможно , вам стоит прибегнуть к наследованию, что сократит дублирование кода.
Я долго думал над примером, не хотелось что-то мифического. На своей работе я имею дело с печатным производством. На печатной фабрике большая разновидность машин: различные виды печатных станков (printing press, uv press), ламинатор (laminating machine), ксерокс (copier) и так далее.
(AbstractMachine.php) download
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
abstract class AbstractMachine
{
const PRINTING_PRESS = 'printing press' ;
const UV_PRESS = 'uv press' ;
const LAMINATING_MACHINE = 'laminating machine' ;
const COPIER = 'copier' ;
/**
* @var string
*/
private $name ;
/**
* @var string
*/
private $vendorName ;
/**
* @var integer
*/
private $year ;
/**
* @return string
*/
abstract public function getType ();
/**
* @return string
*/
public function getName ()
{
return $this -> name ;
}
/**
* @param string $name
*/
public function setName ( $name )
{
$this -> name = $name ;
}
/**
* @return string
*/
public function getVendorName ()
{
return $this -> vendorName ;
}
/**
* @param string $vendorName
*/
public function setVendorName ( $vendorName )
{
$this -> vendorName = $vendorName ;
}
/**
* @return integer
*/
public function getYear ()
{
return $this -> name ;
}
/**
* @param integer $year
*/
public function setYear ( $year )
{
$this -> year = $year ;
}
}
(PrintingPress.php) download
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
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class PrintingPress extends AbstractMachine
{
/**
* @var integer
*/
private $speed ;
/**
* @return boolean
*/
public function isDuplexPrinting ()
{
return true ;
}
/**
* @return boolean
*/
public function isQuickPrint ()
{
return true ;
}
/**
* @return integer
*/
public function getSpeed ()
{
return true ;
}
/**
* @return string
*/
public function getType ()
{
return self :: PRINTING_PRESS ;
}
}
(UvPress.php) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class UvPress extends AbstractMachine
{
/**
* @return string
*/
public function getType ()
{
return self :: UV_PRESS ;
}
}
(LaminatingMachine.php) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class LaminatingMachine extends AbstractMachine
{
/**
* @return string
*/
public function getType ()
{
return self :: LAMINATING_MACHINE ;
}
}
(Copier.php) download
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
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Copier extends AbstractMachine
{
/**
* @return string
*/
public function getType ()
{
return self :: COPIER ;
}
/**
* @return integer
*/
public function getPrintingSpeed ()
{
return 100 ;
}
/**
* @return integer
*/
public function getScanSpeed ()
{
return 10 ;
}
}
Мы вынесли общие части связанных объектов в абстрактный класс, а специфические свойства реализовали в классах потомках.
Какие потенциальные ошибки мы при этом допустили? Исправьте код.
Еще часто прибегают к наследованию, когда у вас есть какой-то класс (возможно из другой библиотеки), и вам понадобилось расширить его функционал.
(User.php) download
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
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class User
{
/**
* @var integer
*/
private $id ;
/**
* @var string
*/
private $username ;
/**
* @var string
*/
private $password ;
/**
* @return string
*/
public function getUsername ()
{
return $this -> username ;
}
//another methods
}
(AdminUser.php) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class AdminUser extends User
{
/**
* @param string $username
*/
public function removeUser ( $username )
{
//code
}
/**
* @param string $username
*/
public function banUser ( $username )
{
//code
}
}
Наследование - это не золотая пуля.
Практически все классы, работающие с базой данных, имеют поле id
. Но это не означает, что нужно создать базовый класс и наследовать от него все остальные.
(BasicClass.php) download
1
2
3
4
5
6
7
8
9
10
11
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
abstract class BasicClass
{
/**
* @var integer
*/
protected $id ;
}
(User.php) download
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
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class User extends BasicClass
{
/**
* @var string
*/
private $username ;
/**
* @var string
*/
private $password ;
/**
* @return string
*/
public function getUsername ()
{
return $this -> username ;
}
//another methods
}
(News.php) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class News extends BasicClass
{
/**
* @var string
*/
private $author ;
/**
* @var string
*/
private $text ;
//another methods
}
Не стоит также смешивать с полиморфизмом. Машина и велосипед имеют колеса, но наличие колес в данном случае - это не некая общность, которую обязательно следует вынести в общий класс.
(Wheel.php) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<? php
/**
* @author Dmitry Petrov <dmitry.petrov@opensoftdev.ru>
*/
class Wheel
{
/**
* @return boolean
*/
public function hasWheels ()
{
//code
}
/**
* @return integer
*/
public function countWheel ()
{
//code
}
}
(Auto.php) download
1
2
3
4
5
<? php
class Auto extends Wheel
{
}
(Bicycle.php) download
1
2
3
4
5
<? php
class Bicycle extends Wheel
{
//code
}