Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Абстрактные классы

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
romantik2011
Отправлено: 26 Июля, 2011 - 23:26:55
Post Id


Новичок


Покинул форум
Сообщений всего: 62
Дата рег-ции: Июль 2011  


Помог: 0 раз(а)




Изучаю полиморфизм - способность класса-родителя использовать функции, классов-потомков, даже если неизвестно реализованы функции-потомков или нет.

Вот написал элементарный код, без реализации, выдаёт ошибку:
PHP:
скопировать код в буфер обмена
  1.  
  2. abstract class Db{
  3.         abstract function db_conn();    
  4.         abstract function db_open();    
  5.         abstract function db_query();    
  6.         abstract function db_close();    
  7. }
  8.  
  9. class B extends Db{
  10.         function db_conn() {};
  11.         function db_open() {};    
  12.         function db_query() {};    
  13.         function db_close() {};  
  14. }
  15.  
  16. $o1 = new B;
  17.  

Цитата:
Parse error: syntax error, unexpected ';', expecting T_FUNCTION in C:\www\htdocs\test.ru\www\index.php on line 11


Дальше, пробую по примеру в книге вот этот код, который в классе-родителе
вызывают функцию из производного класса, но интерпретатор тоже ругается.

PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3.  
  4. class A {
  5. // Выводит, функция какого класса была вызвана
  6. function Test() { echo "Test from A\n"; }
  7. // Тестовая функция — просто переадресует на Test()
  8. function Call() { Test(); }
  9. }
  10. class B extends A {
  11. // Функция Test() для класса B
  12. function Test() { echo "Test from B\n"; }
  13. }
  14. $a=new A();
  15. $b=new B();
  16. $a->Call(); // выводит "Test from A"
  17. $b->Test(); // выводит "Test from B"
  18. $b->Call(); // Внимание! Выводит "Test from B"!
  19.  
  20. ?>
  21.  

Цитата:

Fatal error: Call to undefined function Test() in C:\www\htdocs\test.ru\www\index.php on line 7
 
 Top
OrmaJever Модератор
Отправлено: 26 Июля, 2011 - 23:33:46
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




в первом случае должо быть так
PHP:
скопировать код в буфер обмена
  1. abstract class Db{
  2.         abstract function db_conn();
  3.         abstract function db_open();
  4.         abstract function db_query();
  5.         abstract function db_close();
  6. }
  7.  
  8. class B extends Db{
  9.         function db_conn() {;}
  10.         function db_open() {;}
  11.         function db_query() {;}
  12.         function db_close() {;}
  13. }
  14.  
  15. $o1 = new B;

потому что синтаксис такой.
Во втором случае не удивительно потому что вы в класе обращаетесь к фенкции Test() а надо к $this->test()


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
LIME
Отправлено: 26 Июля, 2011 - 23:42:55
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




OrmaJever пишет:
потому что синтаксис такой.

может потому что абстрактные методы должны быть реализованы в потомках пусть даже пустым оператором?
 
 Top
romantik2011
Отправлено: 26 Июля, 2011 - 23:49:46
Post Id


Новичок


Покинул форум
Сообщений всего: 62
Дата рег-ции: Июль 2011  


Помог: 0 раз(а)




Да, точно, меня интересует пример №1.
Скажите, какой же здесь полиморфизм, как говорится в книге, что мол в методе класса-родителя вызывается метод класса потомка, но объект же создаётся класса-потомка всё-таки.
Вот, смотрите:
PHP:
скопировать код в буфер обмена
  1.  
  2. $a->Call(); // выводит "Test from A"  |объект создался от класса А, значит и функц. класса А вызывается
  3. $b->Test(); // выводит "Test from B"  |объект создался от класса B, значит и функц. класса B вызывается
  4. $b->Call(); // Внимание! Выводит "Test from B"!  |Так здесь наоборот вызывается метод из класса-родителя в классе-потомке, а не в классе-родителя вызывается метод потомка
  5.  


Если полиморфирзм - это когда метод в классе-родителе вызывает метод класса-потомка, я не вижу чтоб здесь в классе-родите вызывался метод-класса-потомка, объект всё равно же создаётся от потомка, а не от родителя.
 
 Top
LIME
Отправлено: 26 Июля, 2011 - 23:56:00
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




romantik2011 пишет:
как говорится в книге, что мол в методе класса-родителя вызывается метод класса потомка,

тут что-то напутано по-моему
полиморфизм это когда переопределяются родительские методы
то есть метод одинаково называется но вызывается свой для каждого класса
другими словами какое-то действие (например прорисовка) выполняется по разному для разного класса (например геометрической фигуры) но вас это не парит вы просто указываете чтото->прорисовать
(Добавление)
romantik2011 пишет:
Так здесь наоборот вызывается метод из класса-родителя в классе-потомке,
все верно ... а то что наоборот было написано это чушь какая-то по моему
поправьте если это не так
 
 Top
OrmaJever Модератор
Отправлено: 27 Июля, 2011 - 00:16:04
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




LIME пишет:
все верно ... а то что наоборот было написано это чушь какая-то по моему

бывает и так
romantik2011 пишет:
Если полиморфирзм - это когда метод в классе-родителе вызывает метод класса-потомка, я не вижу чтоб здесь в классе-родите вызывался метод-класса-потомка, объект всё равно же создаётся от потомка, а не от родителя.

Вот примеду небольшой пример (работать будет только в 5.3 и выше)
PHP:
скопировать код в буфер обмена
  1. class A {
  2.         protected static $a = '$a from class A';
  3.  
  4.         public function getA() {
  5.                 echo static::$a, '<br>';
  6.         }
  7. }
  8.  
  9. class B extends A {
  10.         protected static $a = '$a from class B';
  11.  
  12.         public function __construct() {;}
  13. }
  14.  
  15. $A = new A();
  16. $B = new B();
  17. $A->getA(); // предсказуемо, берёт $a из своего класа
  18. $B->getA(); // берёт $a из класа потомка

У класа B нету метода getA(), поэтому он берётся из родителя, а родительский метод берёт свойство потомка. Причём если в класе В зделать свойство private то будет ругатся что родитель не может получить доступ к потомку. Вот так вот Подмигивание


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
LIME
Отправлено: 27 Июля, 2011 - 00:20:58
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




ага...понятно
на самом деле это не родительский метод а метод потомка но унаследован от родителя
(Добавление)
OrmaJever пишет:
Причём если в класе В зделать свойство private то будет ругатся что родитель не может получить доступ к потомку.
хотя с этим тогда загвоздка ))
 
 Top
OrmaJever Модератор
Отправлено: 27 Июля, 2011 - 00:40:21
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




LIME пишет:
на самом деле это не родительский метод а метод потомка но унаследован от родителя
LIME пишет:
Цитата:
Причём если в класе В зделать свойство private то будет ругатся что родитель не может получить доступ к потомку.

хотя с этим тогда загвоздка ))

сразу обьяснение. Это суровые реалии програмирования Подмигивание


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Stierus Супермодератор
Отправлено: 27 Июля, 2011 - 12:36:44
Post Id



Рекордсмен по количеству сообщений за 7 дней


Покинул форум
Сообщений всего: 2132
Дата рег-ции: Дек. 2008  
Откуда: Москваль


Помог: 52 раз(а)




Цитата:
Причём если в класе В зделать свойство private то будет ругатся что родитель не может получить доступ к потомку.

Родителя нет, есть 1 класс, у которого часть методов описаны в нем самом, часть методов наследуется. А ругаться будет не на то, что мифический родитель не может получить доступ к потомку, а в том, что ты пытаешься переопределить область видимости переменной, этого делать нельзя.
 
My status
 Top
Мелкий Супермодератор
Отправлено: 27 Июля, 2011 - 12:48:56
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Stierus пишет:
а в том, что ты пытаешься переопределить область видимости переменной, этого делать нельзя.

Можно. Не так давно полдня искал косяк:
PHP:
скопировать код в буфер обмена
  1. class a {
  2. private $aaa='aaa';
  3. public function getaa() {
  4. var_dump($this->aaa);
  5. }
  6. }
  7.  
  8. class b extends a {
  9. protected $aaa='bbb';
  10.  
  11. public function getba() {
  12. var_dump($this->aaa);
  13. }
  14. }
  15.  
  16. $c = new b;
  17. $c->getba();
  18. $c->getaa();

PHP5.3, работает, зараза.

А ещё так переопределяет:
PHP:
скопировать код в буфер обмена
  1. class a {
  2. protected $aaa='aaa';
  3. public function getaa() {
  4. var_dump($this->aaa);
  5. }
  6. }
  7.  
  8. class b extends a {
  9. public $aaa='bbb';
  10.  
  11. public function getba() {
  12. var_dump($this->aaa);
  13. }
  14. }
  15.  
  16. $c = new b;
  17. $c->getba();
  18. $c->getaa();


Или "нельзя" имелось в виду, что возможно, но делать так не надо?

(Отредактировано автором: 27 Июля, 2011 - 12:49:43)



-----
PostgreSQL DBA
 
 Top
Stierus Супермодератор
Отправлено: 27 Июля, 2011 - 12:51:21
Post Id



Рекордсмен по количеству сообщений за 7 дней


Покинул форум
Сообщений всего: 2132
Дата рег-ции: Дек. 2008  
Откуда: Москваль


Помог: 52 раз(а)




Под нельзя имелось ввиду, что если у родителя приватное свойство - потомок его тупо не видит и моеж определить свое с т аким же именем, а вот если у родителя паблик, а в потомке ты из паблик попытаешься сделать приват - тебя пошлет лесом.
(Добавление)
Возможно в php 5.3 ситуацию исправили, в php 5.2 точно
 
My status
 Top
Мелкий Супермодератор
Отправлено: 27 Июля, 2011 - 13:06:43
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Да, public ругается.
private - запросто появляется ещё одно свойство, protected - свойство заменяется.


-----
PostgreSQL DBA
 
 Top
OrmaJever Модератор
Отправлено: 27 Июля, 2011 - 16:32:58
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Stierus пишет:
Родителя нет, есть 1 класс, у которого часть методов описаны в нем самом, часть методов наследуется. А ругаться будет не на то, что мифический родитель не может получить доступ к потомку, а в том, что ты пытаешься переопределить область видимости переменной, этого делать нельзя.

Нет, вот такой пример
PHP:
скопировать код в буфер обмена
  1. class A {
  2.         private static $a = '$a from class A';
  3.  
  4.         public function getA() {
  5.                 echo static::$a, '<br>';
  6.         }
  7. }
  8.  
  9. class B extends A {
  10.         private static $a = '$a from class B';
  11.  
  12.         public function __construct() {;}
  13. }
  14.  
  15. $A = new A();
  16. $B = new B();
  17. $A->getA(); // предсказуемо, берёт $a из своего класа
  18. $B->getA(); // берёт $a из класа потомка

выводит
CODE (htmlphp):
скопировать код в буфер обмена
  1. $a from class A
  2.  Fatal error: Cannot access private property B::$a in ...

Поэтому родительно не может обратится к потомку Подмигивание


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Объектно-ориентированное программирование »


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



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB