[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Абстрактные классы
romantik2011
Изучаю полиморфизм - способность класса-родителя использовать функции, классов-потомков, даже если неизвестно реализованы функции-потомков или нет.

Вот написал элементарный код, без реализации, выдаёт ошибку:

abstract class Db{
abstract function db_conn();
abstract function db_open();
abstract function db_query();
abstract function db_close();
}

class B extends Db{
function db_conn() {};
function db_open() {};
function db_query() {};
function db_close() {};
}

$o1 = new B;

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


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


<?php

class
A {
// Выводит, функция какого класса была вызвана
function Test() { echo "Test from A\n"; }
// Тестовая функция — просто переадресует на Test()
function Call() { Test(); }
}

class B extends A {
// Функция Test() для класса B
function Test() { echo "Test from B\n"; }
}

$a=new A();
$b=new B();
$a->Call(); // выводит "Test from A"
$b->Test(); // выводит "Test from B"
$b->Call(); // Внимание! Выводит "Test from B"!

?>

Цитата

Fatal error: Call to undefined function Test() in C:\www\htdocs\test.ru\www\index.php on line 7




Спустя 5 минут, 51 секунда (26.07.2011 - 23:35) alex12060 написал(а):
Во первых, точка с запятой не ставится.

Не



class B extends Db{
function db_conn() {};
function db_open() {};
function db_query() {};
function db_close() {};
}


А


class B extends Db {
function db_conn() {}
function db_open() {}
function db_query() {}
function db_close() {}
}



Далее, внутри класса методы вызываются при помощи ключевого слова $this


class A {
// Выводит, функция какого класса была вызвана
function Test() { echo "Test from A\n"; }
// Тестовая функция — просто переадресует на Test()
function Call() { $this->Test(); }
}

class B extends A {
// Функция Test() для класса B
function Test() { echo "Test from B\n"; }
}

$a=new A();
$b=new B();
$a->Call(); // выводит "Test from A"
$b->Test(); // выводит "Test from B"
$b->Call(); // Внимание! Выводит "Test from B"!


Спустя 6 минут, 4 секунды (26.07.2011 - 23:41) kristall написал(а):
В первом примере ; вообще не надо ставить. Ни после круглых, ни после фигурных скобок.

Спустя 1 минута, 49 секунд (26.07.2011 - 23:43) alex12060 написал(а):
kristall

точно, пардон smile.gif

Спустя 8 минут, 39 секунд (26.07.2011 - 23:52) romantik2011 написал(а):
Да, точно, меня интересует пример №1.
Скажите, какой же здесь полиморфизм, как говорится в книге, что мол в методе класса-родителя вызывается метод класса потомка, но объект же создаётся класса-потомка всё-таки.
Вот, смотрите:

$a->Call(); // выводит "Test from A" |объект создался от класса А, значит и функц. класса А вызывается
$b->Test(); // выводит "Test from B" |объект создался от класса B, значит и функц. класса B вызывается
$b->Call(); // Внимание! Выводит "Test from B"! |Так здесь наоборот вызывается метод из класса-родителя в классе-потомке, а не в классе-родителя вызывается метод потомка


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

Спустя 10 минут, 58 секунд (27.07.2011 - 00:03) Invis1ble написал(а):
romantik2011
где написано, что в родителях можно юзать функционал потомков? blink.gif



Спустя 10 минут, 3 секунды Invis1ble написал(а):
Цитата
Понимаешь, что при наследовании, родителем становится наследующий класс, а не наследуемый.

мде.... я конечно не знаток ООП, но помоему тут бред написан, не? приведи пример, когда класс, наследующий другой класс, становится родителем



Спустя 12 минут, 16 секунд Invis1ble написал(а):
хехе biggrin.gif



Спустя 13 минут, 57 секунд Invis1ble написал(а):
romantik2011
Цитата
полиморфизм - способность класса-родителя использовать функции, классов-потомков, даже если неизвестно реализованы функции-потомков или нет.

дай ссылку плиз, где ты такое определение увидел

 ! 

М
Пожалуйста не надо плодить столько своих постов подряд. Лучше обновлять и использовать UDP
PHPprogrammer

Спустя 46 минут, 2 секунды (27.07.2011 - 00:49) romantik2011 написал(а):
дай ссылку плиз, где ты такое определение увидел

Это определение понятия я сам написал на основе разных источников.

Полиморфизм (многоформенность) является следствием идеи наследования. В общих словах, полиморфность класса — это свойство базового класса использовать функции производных классов, даже если на момент определения еще неизвестно, какой именно класс будет включать его в качестве базового и, тем самым, становиться от него производным.

Вот, смотрите:
это свойство базового класса использовать функции производных классов, 

http://php.su/learnphp/phpoo/?cp

Спустя 1 час, 42 минуты, 50 секунд (27.07.2011 - 02:32) Invis1ble написал(а):
huh.gif
ИМХО, либо здесь ошибка в формулировке, либо я неправильно понимаю смысл этой формулировки....
Базовый класс не может использовать функционал потомков. Ну как такое может вообще быть?! Если я не прав, поправьте меня кто-нибудь пожалуйста! Желательно с примером. А то у меня когнитивный диссонанс развиваться начал....

В том примере (в первом посте) объект дочернего класса B как раз таки использует функционал родителя A, но никак не наоборот.

Спустя 8 часов, 45 минут, 9 секунд (27.07.2011 - 11:17) alex12060 написал(а):
Invis1ble

Да, ты прав smile.gif
Потомок работает со всеми свойствами и методами родителя, а родитель не знает о функционале потомка. Односоронняя связь smile.gif

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

Спустя 2 часа, 7 минут, 20 секунд (27.07.2011 - 13:24) Gradus написал(а):
alex12060, однако смелые заявления :)
Invis1ble, вот вам пример из той ссылки:

class A {
// Выводит, функция какого класса была вызвана
function Test() { echo "Test from A\n"; }
// Тестовая функция — просто переадресует на Test()
function Call() { $this->Test(); }
}

class B extends A {
// Функция Test() для класса B
function Test() { echo "Test from B\n"; }
}

$a=new A();
$b=new B();
$a->Call(); // выводит "Test from A"
$b->Test(); // выводит "Test from B"
$b->Call(); // Внимание! Выводит "Test from B"!

вот свой пример:
class Setter {
function __construct(){
$this->b=10;
$this->abd();
}
}


class Dsdsd extends Setter {
public $b=5;
function abd() {
echo 'work num='.$this->b;
}
}

$foo = new Dsdsd; //выведет work num=10

Спустя 13 минут, 45 секунд (27.07.2011 - 13:38) Invis1ble написал(а):
Gradus
в твоем примере да, есть такое, но в том - нет, поэтому я не понял сразу, о чем идет речь

Спустя 1 день, 6 часов, 26 минут, 12 секунд (28.07.2011 - 20:04) Winston написал(а):
Объясните и мне плиз, что такое полиморфизм.
Нифига я не понял зачем этот кит? И какие его ф-и? sad.gif

Спустя 22 минуты, 2 секунды (28.07.2011 - 20:26) alex12060 написал(а):
PHPprogrammer

Ну, допустим создается абстрактный класс и его наследуют разные классы, изменяя их функционал самостоятельно.

К полиморфности относятся интерфейсы и абстракные классы.

Спустя 16 минут, 47 секунд (28.07.2011 - 20:43) Winston написал(а):
Цитата (alex12060 @ 28.07.2011 - 20:26)
создается абстрактный класс и его наследуют разные классы, изменяя их функционал самостоятельно

Это и есть полиморфизм ?

Спустя 6 минут, 22 секунды (28.07.2011 - 20:49) alex12060 написал(а):
PHPprogrammer

Ну судя wikipedia, то да.

Спустя 22 минуты, 13 секунд (28.07.2011 - 21:11) Winston написал(а):
Здесь его не видно вроде, или я слепой? unsure.gif
Хотя написано, что полим.

Спустя 2 минуты, 48 секунд (28.07.2011 - 21:14) alex12060 написал(а):
PHPprogrammer


class Figure
{
protected $type = '';
public function getArea() {}
public function getPerimeter() {}
public function getType()
{
if ($this->type == '') return 'Неопределен';
else return $this->type;
}
}



Как ты мог заметить, методы getArea(), getPerimeter(), getType() - не имеют реализации в базовом классе, а реализуются в дочернем.

Спустя 57 минут, 39 секунд (28.07.2011 - 22:12) Winston написал(а):
Это я заметил.
Но класс не абстрактный, так можно ?
И разве в дочерних не перегрузка методов ?

Спустя 3 часа, 9 минут, 26 секунд (29.07.2011 - 01:21) Gradus написал(а):
PHPprogrammer, можно.Только немного другой принцип один из них и является перегрузкой методов smile.gif

Спустя 15 часов, 55 минут, 33 секунды (29.07.2011 - 17:17) Winston написал(а):
Цитата (Gradus @ 29.07.2011 - 01:21)
Только немного другой принцип один из них и является перегрузкой методов

Если наследование идет от абстрактных классов, то при перегрузка методов реализуется полиморфизм, а если от обычного класса то просто наследование? unsure.gif

Спустя 32 минуты, 35 секунд (29.07.2011 - 17:49) Gradus написал(а):
С абстрактными классами перегрузки нету, т.к. абстракт не может реализовать абстрактные методы (только прототип), а реализация только в дочерних.В обычных классах идёт перегрузка, но реализация может содержатся как в базовых так и производных классах.В том и другом случае идёт полиморфизм поскольку одинаковые методы с возможностью собственной реализацией есть везде smile.gif

Спустя 5 минут, 10 секунд (29.07.2011 - 17:55) Winston написал(а):
Цитата (Gradus @ 29.07.2011 - 17:49)
В том и другом случае идёт полиморфизм поскольку одинаковые методы

То есть, если одинаковые методы в базовом и дочернем классе имеют свою реализацию, то это полиморфизм ? huh.gif

Спустя 2 минуты, 40 секунд (29.07.2011 - 17:57) Gradus написал(а):
PHPprogrammer, ага.О чём нам подсказывает и вики
Цитата
возможность объектов с одинаковой спецификацией иметь различную реализацию

Спустя 2 дня, 5 часов, 10 минут, 4 секунды (31.07.2011 - 23:07) Guest написал(а):
Цитата (Gradus @ 27.07.2011 - 10:24)
alex12060, однако смелые заявления :)
Invis1ble, вот вам пример из той ссылки:

class A {
// Выводит, функция какого класса была вызвана
function Test() { echo "Test from A\n"; }
// Тестовая функция — просто переадресует на Test()
function Call() { $this->Test(); }
}

class B extends A {
// Функция Test() для класса B
function Test() { echo "Test from B\n"; }
}

$a=new A();
$b=new B();
$a->Call(); // выводит "Test from A"
$b->Test(); // выводит "Test from B"
$b->Call(); // Внимание! Выводит "Test from B"!

вот свой пример:
class Setter {
function __construct(){
$this->b=10;
$this->abd();
}
}


class Dsdsd extends Setter {
public $b=5;
function abd() {
echo 'work num='.$this->b;
}
}

$foo = new Dsdsd; //выведет work num=10

Не верно Invis1ble
Верно alex12060

В приведённом примере связь образует объектная модель, а не классовая, прочувствуйте разницу.
Да, если смотреть со стороны статической конструкции можно натянуть то что метод Call вызывает потомка, но со стороны объекта как и показано этого нет.
Что бы немного словить :
$b->Call(); // Внимание! Выводит "Test from B"!
Объект какого класса имеет метод Call !!! видимо класса "B" smile.gif
Поэтому и метод Call, хоть и унаследованный является "собственностью" потомка а не родителя.

Спустя 8 минут, 3 секунды (31.07.2011 - 23:15) Guest написал(а):
Цитата (PHPprogrammer @ 29.07.2011 - 14:55)
Цитата (Gradus @ 29.07.2011 - 17:49)
В том и другом случае идёт полиморфизм поскольку одинаковые методы

То есть, если одинаковые методы в базовом и дочернем классе имеют свою реализацию, то это полиморфизм ? huh.gif

Не правильное толкование ведёт за собой не правильное понимание.
Полиморфизм создаётся за счёт определения одинаковых интерфейсов (В ТОМ ЧИСЛЕ АБСТРАКТНЫЙ КЛАСС НИ КАК ИНОЕ ИНТЕРФЕЙС). Что такое интерфейс, по простому обычные метод имеющий свою определённую заранее сигнатуру (ИМЕННО ОНА ЯВЛЯЕТСЯ НЕОБХОДИМОЙ ЧАСТЬЮ ДЛЯ ПОЛИМОРФИЗМА ДАБЫ "КЛИЕНТ" МОГ КОРРЕКТНО ОТРАБОТАТЬ С КЛАССОМ), а вот реализация метода внутри уже не имеет для полиморфизма значения.

Спустя 10 минут, 48 секунд (31.07.2011 - 23:26) Guest написал(а):
Цитата (Guest @ 31.07.2011 - 20:07)
Цитата (Gradus @ 27.07.2011 - 10:24)
alex12060, однако смелые заявления :)
Invis1ble, вот вам пример из той ссылки:

class A {
// Выводит, функция какого класса была вызвана
function Test() { echo "Test from A\n"; }
// Тестовая функция — просто переадресует на Test()
function Call() { $this->Test(); }
}

class B extends A {
// Функция Test() для класса B
function Test() { echo "Test from B\n"; }
}

$a=new A();
$b=new B();
$a->Call(); // выводит "Test from A"
$b->Test(); // выводит "Test from B"
$b->Call(); // Внимание! Выводит "Test from B"!

вот свой пример:
class Setter {
function __construct(){
$this->b=10;
$this->abd();
}
}


class Dsdsd  extends Setter {
public $b=5;
function abd() {
echo 'work num='.$this->b;
}
}

$foo = new Dsdsd; //выведет work num=10

Не верно Invis1ble
Верно alex12060

В приведённом примере связь образует объектная модель, а не классовая, прочувствуйте разницу.
Да, если смотреть со стороны статической конструкции можно натянуть то что метод Call вызывает потомка, но со стороны объекта как и показано этого нет.
Что бы немного словить :
$b->Call(); // Внимание! Выводит "Test from B"!
Объект какого класса имеет метод Call !!! видимо класса "B" :)
Поэтому и метод Call, хоть и унаследованный является "собственностью" потомка а не родителя.

Кстати знание, подчёркиваю знание, потомка о методах родителя и родителя о методах потомка (что охрененно создаёт и без того сильную связанность), не является тем что родитель использует метод потомка. В архитектурном сленге вид наследования и называется "прозрачным ящиком", потому как на этапе трансляции (компиляции) связь родитель - потомок прозрачная и видимая, но выходя на объекты уже будет в корне не правильным говорить что родитель использует метод потомка так как это даже физически не правильно (в плане самого ZendEngine)

Спустя 6 минут, 8 секунд (31.07.2011 - 23:32) Winston написал(а):
Guest
Я вижу ты не плохо объясняешь. Зарегиться не хочешь ?

Спустя 12 минут, 6 секунд (31.07.2011 - 23:44) Greg1978 написал(а):
Цитата (PHPprogrammer @ 31.07.2011 - 20:32)
Guest
Я вижу ты не плохо объясняешь. Зарегиться не хочешь ?

Спасибо за предложение, я уже зарегистрирован smile.gif smile.gif , просто пароль не мог вспомнить.

Спустя 8 часов, 39 минут, 14 секунд (1.08.2011 - 08:24) linker написал(а):
Gradus
Твой пример
class Setter {
function __construct(){
$this->b=10;
$this->abd();
}
}


class Dsdsd extends Setter {
public $b=5;
function abd() {
echo 'work num='.$this->b;
}
}

$foo = new Dsdsd; //выведет work num=10
показывает только одно, что конструктор родителя наследуется потомком, а следовательно в контексте потомка код выполнится корректно. В контексте родителя
$foo = new Setter();
получим люлей от PHP и от тех кодеров, которые этот говнокод будут после вас разбирать, ибо родитель ничего не знает про поле $b и метод abd(). Который раз замечаю, что на php.su сидят не слишком умные люди. Класс потомок знает всё про (наследует) public и protected методы родителя, а вот родитель ничего не знает про (не наследует) методы своих потомков. Звиняй, что так резко.

Спустя 9 часов, 56 минут, 16 секунд (1.08.2011 - 18:20) Gradus написал(а):
оу оу что за наезды smile.gif
Цитата
что на php.su сидят не слишком умные люди

я вот думал что эксперты умные, а вы такие глупые выдуманные предъявы выкидываете smile.gif да и каким боком вообще тут php.su приписали))))
Примеры к тому и примеры что бы их понять, а не использовать не осознавая их действия.Вы уклонились в сторону из за гов*кода, говорили о полиморфизме.Правильно не правильно в этой теме роли не играет, от того что не надо писать $$a=10; не означает что это не php, наследование есть полиморфизм есть о чём разговор ? взбесил пример ?) ну вот вам тогда уж контрольный в голову
001001111012001010 biggrin.gif

Спустя 13 часов, 33 минуты, 59 секунд (2.08.2011 - 07:54) linker написал(а):
Gradus
Да ты не обижайся. Я в ответ на
Цитата
Полиморфизм (многоформенность) является следствием идеи наследования. В общих словах, полиморфность класса — это свойство базового класса использовать функции производных классов
сей опус лежит тут http://php.su/learnphp/phpoo/?cp - большей чушни я ещё никогда не слышал. Родитель действительно ничего не должен знать о своих потомках, если я из твоего примера объявлю ещё один класс, потомка Setter, но не реализую метод abd(), то получим ошибку. Для того, чтобы заставлять потомков реализовывать методы существуют куда более приличные методы: абстрактные классы/методы, интерфейсы, всё остальное, уж извини и не обижайся, говнокод.

Спустя 4 часа, 8 минут, 25 секунд (2.08.2011 - 12:02) Gradus написал(а):
Цитата
уж извини и не обижайся, говнокод.

я в жизни такой код не пишу smile.gif
Цитата
я из твоего примера объявлю ещё один класс, потомка Setter, но не реализую метод abd(), то получим ошибку.

ну как бы КЭП smile.gif да и зачем работать с этим примером.
Цитата
сей опус лежит тут http://php.su/learnphp/phpoo/?cp - большей чушни я ещё никогда не слышал.

честно говоря не читал, я больше в вики читаю.

Спустя 42 минуты, 53 секунды (2.08.2011 - 12:45) linker написал(а):
Gradus
Вики тоже сойдёт, а лучше книги мэтров ООП smile.gif

Спустя 8 минут, 27 секунд (2.08.2011 - 12:54) Gradus написал(а):
Цитата
а лучше книги мэтров ООП

и не только в php smile.gif

Спустя 1 час, 35 минут, 16 секунд (2.08.2011 - 14:29) linker написал(а):
Об чём и речь.

Спустя 51 минута, 41 секунда (2.08.2011 - 15:21) Gradus написал(а):
ну я уже прочёл опп в php и c++ , actionscript хотелось бы smile.gif
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.