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

Форум PHP

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

 

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

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

тема: Наследование в классах
 
 автор: darkozoid   (11.06.2013 в 08:53)   письмо автору
 
 

в продолжение темы http://www.softtime.ru/forum/read.php?id_forum=2&id_theme=89652&page=1

<?
class a
public 
$ar
  function 
__construct(){ 
    
$this->ar='что то очень важное и часто нужное'
  } 
  function 
sd(){ 
    print 
$this->ar.".....A::sd<br>"
  }  

class 
extends a
  function 
name($str){ 
    
$this->ar=$str
        print 
$this->ar;
  } 

class 
nn extends a
  function 
name(){ 
    print 
$this->ar
  } 


$obj1=new a;
$obj1->sd(); // $ar = что то очень важное и часто нужное
$obj2=new n;
$obj2->name("что то другое<br>"); // $ar = что то другое
$obj3=new nn;
$obj3->name(); // $ar = что то очень важное и часто нужное
?>

>Хм... действительно значение осталось исходным...

>тогда возникает вопрос, а как же ее (переменную) можно поменять, так, чтобы она наследовалась с новым значением?

>и второй вопрос:
>Почему
$obj3=new nn;
$obj3->name(); // $ar = что то очень важное и часто нужное
>работает, а
nn::name(); 
>нет?

  Ответить  
 
 автор: Sfinks   (11.06.2013 в 09:47)   письмо автору
 
   для: darkozoid   (11.06.2013 в 08:53)
 

> тогда возникает вопрос, а как же ее (переменную) можно поменять, так, чтобы
> она наследовалась с новым значением?

Наследуется переменная как есть. Если Вам нужно изменить ее значение, берете и меняете. Ваш метод класса n вполне с этим справляется.
Если нужно менять автоматом, можно переопределить конструктор:
<?php
  
class extends a{
    public function 
__construct$str ){
      
$this->ar=$str;  
    }  
  }
  
$obj = new n'новое значение' );

> Почему ..... работает, а ..... нет?
потому что не создав (new) класс можно обращаться только к статичным методам.
Вот так работать будет:
<?php
  
class a{
    public 
$var 'значение';
    public static function 
b(){
      echo
"что-то";
    }
  }
  
a::b();
но при этом не забывайте, что экземпляр класса при этом не создается, т.е. если вы в методе b напишете
echo $this->var;
то значения не увидите.

  Ответить  
 
 автор: darkozoid   (11.06.2013 в 10:28)   письмо автору
 
   для: Sfinks   (11.06.2013 в 09:47)
 

>Наследуется переменная как есть. Если Вам нужно изменить ее значение, берете и меняете. Ваш метод класса n вполне с этим справляется.

так я же ее уже изменил, почему она опять исходная?
сначала один класс выводит исходную переменную, потом второй ее меняет, а затем третий выводит опять исходную... как так то? как же мне ее поменять, что бы совсем...

  Ответить  
 
 автор: Sfinks   (11.06.2013 в 11:17)   письмо автору
 
   для: darkozoid   (11.06.2013 в 10:28)
 

Вы не путайте. Вы работаете не с классами, а с экземплярами класса!
Если у вас есть
<?php
  
class extends a
    public function 
__construct$str ){ 
      
$this->ar=$str;   
    }   
  } 
, то
<?php
  $obj1 
= new n'значение1' );
  
$obj2 = new n'значение2' );
  
$obj3 = new n'значение3' );
  echo 
$obj1->ar;   // выведет значение1
  
echo $obj2->ar;   // выведет значение2
  
echo $obj3->ar;   // выведет значение3

Представьте, что у вас есть форма для отливки болванок. Вот класс - это форма.
А в коде выше мы с помощью этой формы отлили 3 болванки и из каждой вырезали 3 разных детали.

> как же мне ее поменять, что бы совсем...
Для этого нужно не новую болванку отливать при каждом действии, а допиливать существующую:
<?php
  $obj1 
= new n'значение1' );
  
$obj1_link1 $obj1;
  
$obj1_link2 $obj1_link1;
  echo 
$obj1->ar;         // выведет значение1
  
echo $obj1_link1->ar;   // выведет значение1
  
echo $obj1_link2->ar;   // выведет значение1
  
$obj1->ar 'Новое значение';
  echo 
$obj1_link2->ar;   // выведет Новое значение
При этом вы каждый раз обращаетесь к одному и тому же экземпляру класса.

  Ответить  
 
 автор: darkozoid   (11.06.2013 в 12:30)   письмо автору
 
   для: Sfinks   (11.06.2013 в 11:17)
 

 
echo $obj1_link1->ar;   // выведет значение1 
  echo $obj1_link2->ar;   // выведет значение1 
  $obj1->ar = 'Новое значение'; 
  echo $obj1_link2->ar;   // выведет Новое значение

а echo $obj1_link2->ar и echo $obj1->ar выведут старое значение так?
а как же тогда классы наследники? если они будут использовать эту переменную, то она будет равна значению 1...
... ну все... теперь я окончательно запутался.... ))

  Ответить  
 
 автор: Sfinks   (11.06.2013 в 13:27)   письмо автору
 
   для: darkozoid   (11.06.2013 в 12:30)
 

> а echo $obj1_link2->ar и echo $obj1->ar выведут старое значение так?
Нет, они выведут тоже новое значение.
Я не зря обозвал переменные с суффиксом _link, т.к. это не копии первого объекта, а всего лишь ссылки на него.
Для создания копии (клона) экземпляра объекта используется одноименный оператор:
<?php 
  $obj1 
= new n'значение1' ); 
  
$obj2 = clone $obj1
  
$obj3 = clone $obj1
  echo 
$obj1->ar;   // выведет значение1 
  
echo $obj2->ar;   // выведет значение1 
  
echo $obj3->ar;   // выведет значение1 
  
$obj2->ar 'Новое значение'
  echo 
$obj1->ar;   // выведет значение1 
  
echo $obj2->ar;   // выведет Новое значение
  
echo $obj3->ar;   // выведет значение1

> а как же тогда классы наследники? если они будут использовать эту переменную
Еще раз....
Разделите напрочь в голове понятия КЛАСС и ОБЪЕКТ (экземпляр класса)
А теперь еще нужно осознать чем отличаются ОБЪЕКТ, ССЫЛКА на объект, КЛОН объекта.

> ... ну все... теперь я окончательно запутался.... ))
=)

  Ответить  
 
 автор: psychomc   (11.06.2013 в 12:33)   письмо автору
 
   для: Sfinks   (11.06.2013 в 09:47)
 

>не создав (new) класс

не класс, объект (экземпляр класса)

  Ответить  
 
 автор: Sfinks   (11.06.2013 в 13:11)   письмо автору
 
   для: psychomc   (11.06.2013 в 12:33)
 

Ну да, ну да, оговорился =) Второй раз меня ловите на этом =)

  Ответить  
 
 автор: psychomc   (11.06.2013 в 13:15)   письмо автору
 
   для: Sfinks   (11.06.2013 в 13:11)
 

извините) привычка. вдалбливали нам этот ооп в универе, таким вещам много уделялось внимания..

  Ответить  
 
 автор: Sfinks   (11.06.2013 в 13:29)   письмо автору
 
   для: psychomc   (11.06.2013 в 13:15)
 

> извините)
Не за что. Вы все правильно делаете.
А то получается, что я объясняю в чем разница между классом и экземпляром класса, а сам говорю не правильно и путаю человека.

  Ответить  
 
 автор: darkozoid   (11.06.2013 в 16:44)   письмо автору
 
   для: Sfinks   (11.06.2013 в 13:29)
 

ладно кашу в голове попробую устранить...


<?
class db extends mysqli
public 
$ressql;
    function 
__construct(){
        
/////////////// config ///////////////////
        
$bd_host="localhost"//host
        
$bd_user="testdomean"// user
        
$bd_pass="5555555"// pass
        
$bd_name="testdomean"// bd_name
        //////////////////////////////////////////
        
$mysqli = new mysqli($bd_host$bd_user$bd_pass$bd_name);
        if (
$mysqli->connect_error) {
            die(
'Connect Error (' $mysqli->connect_errno ') ' $mysqli->connect_error);
        }
        if(
$mysqli){print"ok i`m connect to data base<br>";}
    }
    function 
sql($sql){
    
// запрос
        
if ($mysqli->query($sql)) {
            print 
"query ok<br>";
        }
        else{
            print 
"query error<br>";
        }
        print 
"I live!<br>";
    }

$obj=new db;
$obj->sql('SELECT* FROM test');
?>


результат

ok i`m connect to data base

а где query ok или query error? ну или черт с ними... где I live!

почему они не появляются то... хоть бы что написал то , так нет же... в чем моя ошибка?

  Ответить  
 
 автор: Sfinks   (12.06.2013 в 09:25)   письмо автору
 
   для: darkozoid   (11.06.2013 в 16:44)
 

> а где query ok или query error?
Смотрим внимательнее....
$mysqli = new mysqli($bd_host, $bd_user, $bd_pass, $bd_name);
Это что вы делаете?
Это вы создаете подключение и присваиваете его переменной, область видимости которой ограничивается методом db::__construct. Т.е. после завершения работы этой функции переменная умирает.
Вероятно вы хотели написать:
$this->ressql = new mysqli($bd_host, $bd_user, $bd_pass, $bd_name);


> ну или черт с ними... где I live!
Вероятно у вас отключен вывод ошибок. Потому что на
if ($mysqli->query($sql))
php должен выдать ошибку (попытка вызвать несуществующий метод), т.к. переменная $mysqli не существует.

Ну и в конце концов
$mysqli = new mysqli($bd_host, $bd_user, $bd_pass, $bd_name);
вообще не так выполняется.
Конструктор всегда возвращает экземпляр класса. Поэтому ничто ничему присваивать не надо.
Делается так:
<?php class db extends mysqli{
  public function 
__construct()
  {
    
$bd_host="localhost"//host 
    
$bd_user="testdomean"// user 
    
$bd_pass="5555555"// pass 
    
$bd_name="testdomean"// bd_name 
    
parent::__construct($bd_host$bd_user$bd_pass$bd_name);
  }
  
// а при использовании унаследованных методов
  
public function sql($sql){      
    if (
$this->query($sql)) { 
      print 
"query ok<br>"
    } 
    else{ 
      print 
"query error<br>"
    } 
    print 
"I live!<br>"
  } 
}
$obj=new db(); 
$obj->sql('SELECT* FROM test');

  Ответить  
 
 автор: darkozoid   (13.06.2013 в 09:10)   письмо автору
 
   для: Sfinks   (12.06.2013 в 09:25)
 

>Это вы создаете подключение и присваиваете его переменной, область видимости которой ограничивается методом db::__construct. Т.е. после завершения работы этой функции переменная умирает.rn>Вероятно вы хотели написать:rn>
$this->ressql = new mysqli($bd_host, $bd_user, $bd_pass, $bd_name);
rnвот где собака порылась.... спасибо....rnrn
parent::__construct($bd_host, $bd_user, $bd_pass, $bd_name); 
rnЭм... если я правильно понимаю, то этой записью мы обращаемся к конструктору родительского класса, а он у нас mysqli... или родитель метода (класс db)?rnВ любом случае встает вопрос: rn- если родитель - класс mysqli - то его конструктор выполняет подключение к базе?rnrnи еще вопрос, а можно как то включить вывод ошибок, то только для этого сайта? (только для этой страницы, даже)?

  Ответить  
 
 автор: Sfinks   (13.06.2013 в 10:43)   письмо автору
 
   для: darkozoid   (13.06.2013 в 09:10)
 

> Эм... если я правильно понимаю, то этой записью мы обращаемся к конструктору
> родительского класса, а он у нас mysqli...

Да, все верно.

> - если родитель - класс mysqli - то его конструктор выполняет подключение к базе?
Да, все верно.

> и еще вопрос, а можно как то включить вывод ошибок, то только для этого сайта?
> (только для этой страницы, даже)?

В начале скрипта пропишите:
error_reporting(E_ALL);

  Ответить  
 
 автор: darkozoid   (13.06.2013 в 17:58)   письмо автору
 
   для: Sfinks   (13.06.2013 в 10:43)
 

>> Эм... если я правильно понимаю, то этой записью мы обращаемся к конструктору
>> родительского класса, а он у нас mysqli...

>Да, все верно.
>
>> - если родитель - класс mysqli - то его конструктор выполняет подключение к базе?
>Да, все верно.
>
а можно как то посмотреть, сто еще делает конструктор mysqli (и вообще класса)

>> и еще вопрос, а можно как то включить вывод ошибок, то только для этого сайта?
>> (только для этой страницы, даже)?

>В начале скрипта пропишите:
>
error_reporting(E_ALL);

спасибо

  Ответить  
 
 автор: Sfinks   (14.06.2013 в 10:19)   письмо автору
 
   для: darkozoid   (13.06.2013 в 17:58)
 

> а можно как то посмотреть, сто еще делает конструктор mysqli (и вообще класса)
http://www.php.net/manual/ru/book.mysqli.php - все эти методы и свойства будут унаследованы вашим классом. И обращаться к ним можно уже через $this->

  Ответить  
 
 автор: darkozoid   (14.06.2013 в 10:32)   письмо автору
 
   для: Sfinks   (14.06.2013 в 10:19)
 

УХ! спасибо...

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

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