Проверьте пожалуйста задание: 1. Создайте базовый класс продукта. 2. Создайте три любых типа продукта (класса), в разных категориях; 3. Все продукты, кроме одного, имеют 10 процентную скидку и их цена должна выводиться с ней; 4. Один тип продукта - имеет скидку только в том случае, если его вес больше 10 килограмм; Используйте примеси, интерфейсы или абстрактные классы в решении задачи. я не знаю, как правильно использовать абстрактные классы и интерфейсы. PHP: <?php header('Content-Type: text/html; charset:utf-8'); error_reporting(-1); abstract class Product{ public function __construct($title, $price, $weight){ $this->title = $title; $this->price = $price; $this->weight = $weight; } } class Planshet extends Product{ public $discount = 10; public function getPrice(){ if ($this->discount) { return round($this->price - ($this->price * $this->discount/100)); } else { return $this->price; } } } class Potato extends Planshet{ public function getPrice(){ if ($this->weight > 10000) { return round($this->price - ($this->price * $this->discount/100)); } else { return $this->price; } } } class Jacket extends Product{} $planshet = new Planshet('Планшет', 2000, 400); $potato = new Potato('Картошка', 700, 4000); $potato2 = new Potato('Ещё картошка', 700, 12000); $jacket = new Jacket('Куртка', 6300, 2000); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <?php echo $planshet->title . ' цена без скидки ' . $planshet->price . ', со скидкой ' . $planshet->getPrice(); echo '<br>'; echo $potato->title . ' цена без скидки ' . $potato->price . ', со скидкой ' . $potato->getPrice(); echo '<br>'; echo $potato2->title . ' цена без скидки ' . $potato2->price . ', со скидкой ' . $potato2->getPrice(); echo '<br>'; echo $jacket->title. ' цена ' . $jacket->price; ?> </body> </html>
Откуда задачи? С курсов? Или сам ищешь? Тебе объясняли что такое полиморфизм и нахрена это всё делается? По коду похоже, что нет. Тебе уже рекомендовали Зандстру - купи (скачай) и прочти, отпадёт большая часть вопросов.
Нужен что бы применять такой же метод у дочернего класса и можно слегка его переделать. В абстрактном классе просто пишется список методов, которые надо реализовать
Ну да, почти. И где у вас первое? Где второе? Вообще, классическое определение: "Полиморфизм позволяет обращаться с объектами производных классов также как с объектами базового класса"
Во, даже опечатку у меня заметил. Поправил. Так поправь теперь свой код Выдели общие операции, вынеси в абстрактный класс, сделай реализацию
Получается так PHP: <?php header('Content-Type: text/html; charset:utf-8'); error_reporting(-1); abstract class Product{ abstract function getPrice(); public function __construct($title, $price, $weight){ $this->title = $title; $this->price = $price; $this->weight = $weight; } } class Planshet extends Product{ public $discount = 10; public function getPrice(){ if ($this->discount) { return round($this->price - ($this->price * $this->discount/100)); } else { return $this->price; } } } class Potato extends Planshet{ public function getPrice(){ if ($this->weight > 10000) { return round($this->price - ($this->price * $this->discount/100)); } else { return $this->price; } } } class Jacket extends Planshet{} $planshet = new Planshet('Планшет', 2000, 400); $potato = new Potato('Картошка', 700, 4000); $potato2 = new Potato('Ещё картошка', 700, 12000); $jacket = new Jacket('Куртка', 6300, 2000); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <?php echo $planshet->title . ' цена без скидки ' . $planshet->price . ', со скидкой ' . $planshet->getPrice(); echo '<br>'; echo $potato->title . ' цена без скидки ' . $potato->price . ', со скидкой ' . $potato->getPrice(); echo '<br>'; echo $potato2->title . ' цена без скидки ' . $potato2->price . ', со скидкой ' . $potato2->getPrice(); echo '<br>'; echo $jacket->title. ' цена ' . $jacket->price; ?> </body> </html>
Ага, чуть больше похоже на правду. Но можно и лучше. Покажи мне, где ты тут обращаешься с объектом производного класса как с объектом базового? И поля закрой, что-ли Инкапсуляция, как-никак должна быть
@Dimon2x, в этом случе скиду стоит вынести в базовый абастранктный класс. И странно что класс Картошки наследует класс планшетов)) --- Добавлено --- Вот для этого продукта можно будет переопределить метод скидки. На мой взгляд так логичнее.
Вот такое получилось PHP: <?php header('Content-Type: text/html; charset:utf-8'); error_reporting(-1); abstract class Product{ abstract function setTitle($title); abstract function getTitle(); abstract function setPrice($price); abstract function getPrice(); abstract function getDiscount(); protected $discount = 10; protected $title; protected $price; } class Planshet extends Product{ public function setTitle($title){ $this->title = $title; } public function getTitle(){ return $this->title; } public function setPrice($price){ $this->price = $price; } public function getPrice(){ return $this->price; } public function getDiscount(){ if ($this->discount) { return round($this->price - ($this->price * $this->discount/100)); } else { return $this->price; } } } $planshet = new Planshet; $planshet->setTitle('Планшет'); $planshet->setPrice('2000'); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <?php echo $planshet->getTitle() . ' цена без скидки ' . $planshet->getPrice() . ', со скидкой ' . $planshet->getDiscount();; echo '<br>'; ?> </body> </html>
Не-а, ты не врубаешься вообще, что к чему. Почитай книжку. Вот зачем ты абстрактными сделал методы, которые можно реализовать и на уровне базового класса. Ну порассуждай немного. Что меняется у разных типов продуктов? Алгоритм подсчёта скидки (кстати, ты и ТЗ не совсем верно понял, по видимому). У части продуктов скидка просто 10%, а у других - зависит от веса. Ну вот это и есть абстрактная функция. А цену можно посчитать как базовая цена минус скидка - это можно вполне, к примеру, разместить и в базовом классе, а также все эти геттеры-сеттеры. Вообще, тут конечно кое-что ещё напрашивается, о чём Зандстра пишет, но не буду сейчас так далеко заходить, чтоб не запутать.
Что я неправильно сделал? Как понять на уровне базового класса, это с помощью конструктора? --- Добавлено --- у них меняется цена и название
Цена и название есть у всех типов продуктов. А вот скидка считается по-разному. На уровне базового класса - значит в самом базовом классе. Ты не мыслишь абстракцией. В общем, книгу тебе порекомендовали, книга шикарная, объяснено всё от основ применения ООП в PHP, до весьма крутых методов его применения. Читай. Пост в форуме столько информации не вместит. По этой задаче тебе всё уже расписали здесь, осталось только за тебя сделать. --- Добавлено --- Вот расскажи, кстати, что такое класс и чем он отличается от объекта?
Получается делать абстрактные методы, только для тех функций, у которых будет разная функциональность? Здесь это определение подходит только для скидки. А как написать свойства, у них же тоже содержимое у всех разное? --- Добавлено --- класс это шаблон, по которому делается объект
Ну ты же писал конструкторы, сеттеры, геттеры. https://php.ru/forum/threads/abstraktnye-klassy-i-nasledovanie.62979/#post-511671 - вот тут ты был ближе всего к наилучшему решению задачи, которое ты можешь на данном уровне предложить. Но ты сделал полиморфорную функцию, а не использовал её преимущества никак Поэтому я тебе и задал вопрос, на который ты ответил неверно. Нет никакого преимущества от полиморфизма, если ты вручную создаёшь объекты, и потом у каждого дёргаешь по одному функцию. А вот если ты пишешь код, который думает, что он работает с Product, а передаёшь в него Planshet, и этот код правильно срабатывает для планшетов, хотя ты ни строчки в нём не менял - вот это использование полиморфизма. По поводу свойств. Свойства не у класса (если речь идёт не о статических свойствах), свойства у объектов. Смекаешь?
Ага. А значения указываются для каждого объекта. И ведь название и цена есть у любых товаров, а не только у планшетов или только у картофелин? Вот то, что у всех общее - это должно быть в базовом классе, то, что отличается - реализуется через полиморфизм.
Пропущено важное слово есть Вот то, что есть у всех общее - это должно быть в базовом классе. Без этого слова, получается, что общего ничего нету.
Вот так сделал PHP: <?php header('Content-Type: text/html; charset:utf-8'); error_reporting(-1); abstract class Product{ public $title; protected $price; public $weight; private $discount = 10; public function getDiscount(){ return $this->discount; } public function getPrice(){ return $this->price; } protected function getPriceDiscount(){ if ($this->getDiscount()) { return round($this->price - ($this->price * $this->getDiscount()/100)); } else { return $this->price; } } public function getFunGetPriceDiscount(){ return $this->getPriceDiscount(); } public function __construct($title, $price, $weight){ $this->title = $title; $this->price = $price; $this->weight = $weight; } } class Planshet extends Product{} class Potato extends Product{ function getFunGetPriceDiscount(){ if($this->weight > 10000){ return parent::getFunGetPriceDiscount(); } else{ return $this->getPrice(); } } } class Jacket extends Product{} $planshet = new Planshet('Планшет', 2000, 400); $potato = new Potato('Картошка', 700, 12000); $jacket = new Jacket('Куртка', 700, 2000); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <?php echo $planshet->title . ' цена без скидки ' . $planshet->getPrice() . ', со скидкой ' . $planshet->getFunGetPriceDiscount(); echo '<br>'; echo $potato->title . ' цена без скидки ' . $potato->getPrice() . ', со скидкой ' . $potato->getFunGetPriceDiscount(); echo '<br>'; echo $jacket->title. ' цена ' . $jacket->getPrice(); ?> </body> </html>
Не, чувак. Нифига ты не понимаешь полиморфизм. У тебя он всё только усложняет, а должен упрощать. PHP: <?php abstract class Product { private $title, $price; public function __construct($t, $p) { $this->title = $t; $this->price = $p; } function getTitle() { return $this->title; } function getPrice() { return $this->price * (1 - $this->getDiscount()); } abstract function getDiscount(); } class ProductWith10PercentDiscount extends Product { function getDiscount() { return 0.1; } } class ProductWithWeightDiscount extends Product { private $weight; public function __construct($t, $p, $w) { parent::__construct($t, $p); $this->weight = $w; } function getDiscount() { return $this->weight < 10 ? 0: 0.1; } } $products = [ new ProductWith10PercentDiscount('Планшет', 2000), new ProductWith10PercentDiscount("Фен", 1000), new ProductWithWeightDiscount("Картошка", 15, 20), new ProductWithWeightDiscount("Морковь", 15, 3) ]; foreach ($products as $p) { echo $p->getTitle() . ' - ' . $p->getPrice() . '<br>'; } Вот на что тут тебя всё наталкивали. Заметь,Product::getPrice() без понятия, как считается скидка, а вот производные классы указывают ей на это
но стало же лучше, чем было? --- Добавлено --- ну у тебя слишком крутой код для новичка --- Добавлено --- в каком месте у меня усложнил? --- Добавлено --- а почему вес не включили в базовый? Он же у всех есть --- Добавлено --- а зачем вы сделали 2 функции скидок, если можно одну? --- Добавлено --- А зачем название делать приватным?