Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Вопрос по ООП php про конструктор класса.
 
 автор: makeloo   (06.02.2014 в 12:14)   письмо автору
 
 

Здравствуйте!
Подскажите пожалуйста зачем при наследовании класса нужно обязательно в дочернем классе также вызывать конструктор родительского класса? Вот пример кода из книги "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;

  Ответить  
 
 автор: psychomc   (06.02.2014 в 13:33)   письмо автору
 
   для: 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;
    }
}

надеюсь доступно объяснил

  Ответить  
 
 автор: Valick   (06.02.2014 в 13:50)   письмо автору
 
   для: psychomc   (06.02.2014 в 13:33)
 

>$this->siski = $siski;
если так учить, да еще и с картинками, то все ООП будут знать на зубок :D

  Ответить  
 
 автор: psychomc   (06.02.2014 в 14:22)   письмо автору
 
   для: Valick   (06.02.2014 в 13:50)
 

да, попытался простимулировать ;)

  Ответить  
 
 автор: makeloo   (06.02.2014 в 14:04)   письмо автору
 
   для: psychomc   (06.02.2014 в 13:33)
 

Теперь понял!!! Классно объяснили на сиськах))) Спасибо!

Значит в дочернем классе нужно вызвать родительский конструктор чтобы инициализировались все члены родительского класса....

То есть если НЕ ВЫЗВАТЬ родительский конструктор то его члены окажутся не инициализированными! И нужно будет их все переписывать в конструкторе дочернего класса.
А вызвав РОДИТЕЛЬСКИЙ конструктор можно просто отдельно инициализировать ТОЛЬКО уникальные члены дочернего класса.

Я уже давно читаю книгу “PHP практика создания веб-сайтов" и другие книги по PHP.. В целом все понятно, но всякие такие нюансы не сразу доходят)))

Еще не понятно зачем нужно некоторые члены объявлять protected а некоторые public.
Я знаю что public доступны из внешнего кода, а protected доступны только в классах-наследниках. Но зачем нужно такое ограничение? Чем плохо объявлять все члены и методы как публичные?

  Ответить  
 
 автор: Valick   (06.02.2014 в 14:11)   письмо автору
 
   для: makeloo   (06.02.2014 в 14:04)
 

так начинать нужно с теории, а вы про практику читаете :) хотя сама по себе книга хорошая, но она далеко не единственная у авторов.

  Ответить  
 
 автор: makeloo   (06.02.2014 в 14:17)   письмо автору
 
   для: Valick   (06.02.2014 в 14:11)
 

Другие книги по php тоже читал. Читал книгу этих же авторов Кузнецов Симдянов " PHP для чайников" (с нее начинал), там есть раздел по ООП но он такой же по содержанию как и в данной книге. Также читал других авторов, но в основном там не затрагивают тему ООП.

Зачем нужно некоторые члены объявлять protected а некоторые public?
Я знаю что public доступны из внешнего кода, а protected доступны только в классах-наследниках. Но зачем нужно такое ограничение? Чем плохо объявлять все члены и методы как публичные?

К примеру в классе field фреймворка софттайм:
все члены объявлены protected
кроме $css_class и $css_style которые объявлены публичными.
В чем практическая польза такого подхода?

  Ответить  
 
 автор: psychomc   (06.02.2014 в 14:28)   письмо автору
 
   для: makeloo   (06.02.2014 в 14:04)
 

>Я знаю что public доступны из внешнего кода, а protected доступны только в классах-наследниках. Но зачем нужно такое ограничение? Чем плохо объявлять все члены и методы как публичные?

это уже называется инкапсуляция. почитайте определение и думаю станет понятно. вообще есть такой негласный принцип хорошего ооп-кода, называется он примерно так: "открытые методы класса, закрытые члены класса". обращение напрямую к члену класса из внешнего кода может привести к плохим последствиям, когда значение этого члена класса до инициализации должно проходить предварительную обработку. да и вообще, метод сам по себе намного более гибкий.
p.s советую вот эту книгу http://www.ozon.ru/context/detail/id/5648968/

  Ответить  
 
 автор: makeloo   (06.02.2014 в 14:35)   письмо автору
 
   для: psychomc   (06.02.2014 в 14:28)
 

Эту книгу купил... Лежит пока на столе. Я так подумал что надо сначало научиться хотя бы говнокодить чтобы читать эту книгу.

Из Вашего ответа я так понял что делать члены класса протектед это аксиома которой стоит ПРОСТО придерживаться))) В смысле можно и объявлять все публик, но тогда будут некие плохие последствия.... Но что к примеру может случиться?

  Ответить  
 
 автор: psychomc   (06.02.2014 в 15:00)   письмо автору
 
   для: 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

  Ответить  
 
 автор: makeloo   (06.02.2014 в 16:40)   письмо автору
 
   для: 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 публичным то ошибки не происходит и код выдает путь к файлу без слеша. Чуть чуть стало понятней.

Спасибо!))

  Ответить  
 
 автор: psychomc   (06.02.2014 в 18:30)   письмо автору
 
   для: makeloo   (06.02.2014 в 16:40)
 

вообще, я почти всегда, если надо закрыть доступ извне, юзаю protected, а не private, давая тем самым изменять эти члены/методы класса наследникам. иногда private может быть полезен, но это достаточно редкие случаи, например паттерн singleton и т.п

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования