|
|
|
| Здравствуйте!
Подскажите пожалуйста зачем при наследовании класса нужно обязательно в дочернем классе также вызывать конструктор родительского класса? Вот пример кода из книги "PHP практика создания веб-сайтов"
class field_text extends field
{
// Размер текстового поля
public $size;
// Максимальный размер вводимых данных
public $maxlength;
// Конструктор класса
function __construct($name,
$caption,
$is_required = false,
$value = "",
$maxlength = 255,
$size = 41,
$parameters = "",
$help = "",
$help_url = "")
{
// Вызываем конструктор базового класса field для
// инициализации его данных
parent::__construct($name,
"text",
$caption,
$is_required,
$value,
$parameters,
$help,
$help_url);
// Инициализируем члены класса
$this->size = $size;
$this->maxlength = $maxlength;
}
|
Почему нельзя просто вызвать конструктор дочернего класса и забыть про родительский класс? И еще вопрос: почему в этом примере кода инициализируются только два члена класса?
$this->size = $size;
$this->maxlength = $maxlength;
|
| |
|
|
|
|
|
|
|
для: makeloo
(06.02.2014 в 12:14)
| | вам бы подучить основные принципы ООП, а именно наследование. смотрите, по своей сути конструктор эта такой же метод класса, как и любой другой, с той лишь разницей, что при создании объекта он вызывается автоматически. при переопределении какого-либо метода в дочернем классе (когда мы в дочернем классе создаем метод с таким же именем, как и в родительском), происходит подмена родительского, т.е дочерний его покрывает (но тем не менее, у нас есть доступ к родительскому через тот же parent:: )
>Почему нельзя просто вызвать конструктор дочернего класса и забыть про родительский класс?
а кто сказал, что нельзя? можно, но в таком случае придется в конструкторе дочернего класса инициализировать всё, что инициализуется в родительском. если этого не делать, то такое наследование просто не имеет смысла.
>И еще вопрос: почему в этом примере кода инициализируются только два члена класса?
потому что это имеет смысл для конкретного наследника. здесь может пример и не совсем интересный. еще нет времени и ничего путного не приходит в голову...например, есть базовый класс человек, в котором описаны наиболее общие характеристики для всех людей разных полов, и есть его наследник, например женщина, которая его расширяет и дополняет. так вот, выглядело бы это примерно так:
<?php
class human
{
protected
$growth, // рост
$weight; // вес
// ...
public function __construct($growth, $weight, ...) {
$this->growth = $growth;
$this->weight = $weight;
// ...
}
}
class woman extends people
{
protected $siski; // ...
public function __construct($siski, $growth, $weight, ...) {
parent::__construct($growth, $weight, ...);
/*
это же короче, чем писать
$this->growth = $growth;
$this->weight = $weight;
правда?
*/
$this->siski = $siski;
}
}
|
надеюсь доступно объяснил | |
|
|
|
|
|
|
|
для: psychomc
(06.02.2014 в 13:33)
| | >$this->siski = $siski;
если так учить, да еще и с картинками, то все ООП будут знать на зубок :D | |
|
|
|
|
|
|
|
для: Valick
(06.02.2014 в 13:50)
| | да, попытался простимулировать ;) | |
|
|
|
|
|
|
|
для: psychomc
(06.02.2014 в 13:33)
| | Теперь понял!!! Классно объяснили на сиськах))) Спасибо!
Значит в дочернем классе нужно вызвать родительский конструктор чтобы инициализировались все члены родительского класса....
То есть если НЕ ВЫЗВАТЬ родительский конструктор то его члены окажутся не инициализированными! И нужно будет их все переписывать в конструкторе дочернего класса.
А вызвав РОДИТЕЛЬСКИЙ конструктор можно просто отдельно инициализировать ТОЛЬКО уникальные члены дочернего класса.
Я уже давно читаю книгу “PHP практика создания веб-сайтов" и другие книги по PHP.. В целом все понятно, но всякие такие нюансы не сразу доходят)))
Еще не понятно зачем нужно некоторые члены объявлять protected а некоторые public.
Я знаю что public доступны из внешнего кода, а protected доступны только в классах-наследниках. Но зачем нужно такое ограничение? Чем плохо объявлять все члены и методы как публичные? | |
|
|
|
|
|
|
|
для: makeloo
(06.02.2014 в 14:04)
| | так начинать нужно с теории, а вы про практику читаете :) хотя сама по себе книга хорошая, но она далеко не единственная у авторов. | |
|
|
|
|
|
|
|
для: Valick
(06.02.2014 в 14:11)
| | Другие книги по php тоже читал. Читал книгу этих же авторов Кузнецов Симдянов " PHP для чайников" (с нее начинал), там есть раздел по ООП но он такой же по содержанию как и в данной книге. Также читал других авторов, но в основном там не затрагивают тему ООП.
Зачем нужно некоторые члены объявлять protected а некоторые public?
Я знаю что public доступны из внешнего кода, а protected доступны только в классах-наследниках. Но зачем нужно такое ограничение? Чем плохо объявлять все члены и методы как публичные?
К примеру в классе field фреймворка софттайм:
все члены объявлены protected
кроме $css_class и $css_style которые объявлены публичными.
В чем практическая польза такого подхода? | |
|
|
|
|
|
|
|
для: makeloo
(06.02.2014 в 14:04)
| | >Я знаю что public доступны из внешнего кода, а protected доступны только в классах-наследниках. Но зачем нужно такое ограничение? Чем плохо объявлять все члены и методы как публичные?
это уже называется инкапсуляция. почитайте определение и думаю станет понятно. вообще есть такой негласный принцип хорошего ооп-кода, называется он примерно так: "открытые методы класса, закрытые члены класса". обращение напрямую к члену класса из внешнего кода может привести к плохим последствиям, когда значение этого члена класса до инициализации должно проходить предварительную обработку. да и вообще, метод сам по себе намного более гибкий.
p.s советую вот эту книгу http://www.ozon.ru/context/detail/id/5648968/ | |
|
|
|
|
|
|
|
для: psychomc
(06.02.2014 в 14:28)
| | Эту книгу купил... Лежит пока на столе. Я так подумал что надо сначало научиться хотя бы говнокодить чтобы читать эту книгу.
Из Вашего ответа я так понял что делать члены класса протектед это аксиома которой стоит ПРОСТО придерживаться))) В смысле можно и объявлять все публик, но тогда будут некие плохие последствия.... Но что к примеру может случиться? | |
|
|
|
|
|
|
|
для: makeloo
(06.02.2014 в 14:35)
| | да всё, что угодно, например:
<?php
class test
{
public $dir;
public function set_dir($dir) {
// приводим директорию к правильному виду для данного класса
// один обязательный слеш на конце
$this->dir = rtrim($dir, '/') . '/';
}
public function get_file_path() {
return $this->dir . $this->filename;
}
}
|
подумайте, что может произойти, если пользователь класса проинициализирует директорию не через метод set_dir, а напрямую обращаясь к члену класса dir не зная, что на конце должен быть слеш и попытается получить путь к файлу через метод get_file_path | |
|
|
|
|
|
|
|
для: psychomc
(06.02.2014 в 15:00)
| |
<?php
class test
{
private $dir;
public $filename;
public function __construct ($dir,$filename)
{
$this->dir = $dir;
$this->filename = $filename;
}
public function set_dir($dir) {
// приводим директорию к правильному виду для данного класса
// один обязательный слеш на конце
$this->dir = rtrim($dir, '/') . '/';
}
public function get_file_path() {
return $this->dir . $this->filename;
}
}
$obj = new test($dir,myfile);
$obj->set_dir(upload);
echo $obj->get_file_path();
echo "<br/>"."<br/>";
$obj->dir = upload; // напрямую инициализируем член класса
echo $obj->get_file_path(); // тут возникает ошибка
?>
|
Такой код приводит к ошибке... Но если сделать член $dir публичным то ошибки не происходит и код выдает путь к файлу без слеша. Чуть чуть стало понятней.
Спасибо!)) | |
|
|
|
|
|
|
|
для: makeloo
(06.02.2014 в 16:40)
| | вообще, я почти всегда, если надо закрыть доступ извне, юзаю protected, а не private, давая тем самым изменять эти члены/методы класса наследникам. иногда private может быть полезен, но это достаточно редкие случаи, например паттерн singleton и т.п | |
|
|
|