Этот урок набрал набрал достаточно большое количество
комментариев и дальнейшее его комментирование отключено.
Если вы хотели убедиться в правильности выполнения ДЗ или у вас возник вопрос по уроку,
посмотрите ранее добавленные комментарии, кликнув по кнопке ниже. Скорее всего вы найдете там то, что искали.
Если это не помогло - задайте вопрос в чате в телеграме - https://t.me/php_zone
$objects = [
new Square(5),
new Rectangle(2,4),
new Circle(9)
];
foreach ($objects as $object){
if ($object instanceof CalcSquare){
echo 'Объект реализует интерфейс CalcSquare. И принадлежит к классу ' . get_class($object) . PHP_EOL ;
}
else {
echo 'Объект НЕ РЕАЛИЗУЕТ интерфейс CalcSquare. И принадлежит к классу ' . get_class($object) . PHP_EOL ;
}
}
class Rectangle
{
private $x;
private $y;
public function __construct(float $x, float $y)
{
$this->x = $x;
$this->y = $y;
}
public function calculateSquare(): float
{
return $this->x * $this->y;
}
}
class Square implements CalculateSquare
{
private $x;
public function __construct(float $x)
{
$this->x = $x;
}
public function calculateSquare(): float
{
return $this->x ** 2;
}
}
interface CalculateSquare
{
public function calculateSquare(): float;
}
class Circle implements CalculateSquare
{
const PI = 3.1416;
private $r;
public function __construct(float $r)
{
$this->r = $r;
}
public function calculateSquare(): float
{
return self::PI * ($this->r ** 2); //self - обращение к текущему классу
}
}
//$circle1 = new Circle(2.5);
// var_dump($circle1 instanceof CalculateSquare); //instanceof - проверяет является ли экзэпляром какого-либо класса, либо реализует какого-либо интерфейс
//get_class Возвращает имя класса к которому принадлежит объект
$objects = [
new Square(5),
new Rectangle(2, 4),
new Circle(5)
];
//var_dump($objects);
//echo (get_class($objects[0]));
//echo '<br>';
foreach ($objects as $object) {
if ($object instanceof CalculateSquare) {
echo 'Объект реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare() . ' и это объект класса ' . get_class($object);
echo '<br>';
}
else {
echo 'Объект класса ' . get_class($object) . ' не реализует интерфейс CalculateSquare. ';
echo '<br>';
}
}
Познакомьтесь самостоятельно с функцией get_class().
Дополните информацию об объекте, для которого считается площадь – пишите что это объект такого-то класса.
Для объектов, которые не реализуют интерфейс CalculateSquare пишите:
Объект класса ТУТ_НАЗВАНИЕ_КЛАССА не реализует интерфейс CalculateSquare.
interface CalculateSquare
{
public function calculateSquare(): float;
}
class Rectangle implements CalculateSquare
{
private $x;
private $y;
public function __construct(float $x, float $y)
{
$this->x = $x;
$this->y = $y;
}
public function calculateSquare(): float
{
return $this->x * $this->y;
}
}
class Square
{
private $x;
public function __construct(float $x)
{
$this->x = $x;
}
public function calculateSquare(): float
{
return $this->x ** 2;
}
}
class Circle implements CalculateSquare
{
private $r;
const PI = 3.1416;
public function __construct(float $r)
{
$this->r = $r;
}
public function calculateSquare(): float
{
return self::PI * ($this->r ** 2);
}
}
$objects = [
new Square(5),
new Rectangle(2, 4),
new Circle(5)
];
foreach ($objects as $object) {
if ($object instanceof CalculateSquare) {
echo 'Объект ' . get_class($object) . ' реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare();
echo '<br>';
}
else{
echo 'Объект класса ' . get_class($object) . ' не реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare();
echo '<br>';
}
}
interface CalculateSquare
{
public function calculateSquare();
}
class Circle implements CalculateSquare
{
const PI = 3.14;
private $r;
public function __construct($r)
{
$this->r = $r;
}
public function calculateSquare()
{
return self::PI * ($this->r ** 2);
}
}
class Rectangle implements CalculateSquare
{
private $a;
private $b;
public function __construct($a, $b)
{
$this->a = $a;
$this->b = $b;
}
public function calculateSquare()
{
return $this->a * $this->b;
}
}
class Square implements CalculateSquare
{
private $a;
public function __construct($a)
{
$this->a = $a;
}
public function calculateSquare()
{
return $this->a ** 2;
}
}
$all = [
new Circle(7),
new Square(4),
new Rectangle(4, 3)
];
foreach ($all as $value) {
if ($value instanceof CalculateSquare) {
echo '<p> Площадь равна = ' . $value->calculateSquare() . 'Это объект класса - ' . get_class($value);
} else {
echo 'Объект класса' . get_class($value) . 'не реализует интерфейс CalculateSquare';
}
}
Вопрос по поводу типизации данных. PhpStorm выдает ошибку если указывать эту строгую типизацию.
Насколько это грозит последствиями если ее не указывать?
P.S. Новое для себя открыл, крутое выражение возведение в степень **2.
По коду - ок. Шторм правильно всё говорит, если ожидаете целочисленное, то и передавать нужно целочисленное. Лучше сейчас использовать strict_types=1 уже.
Дополните информацию об объекте, для которого считается площадь – пишите что это объект такого-то класса.
Для объектов, которые не реализуют интерфейс CalculateSquare пишите:
Объект класса ТУТ_НАЗВАНИЕ_КЛАССА не реализует интерфейс CalculateSquare.
foreach ($objects as $key => $object) {
if ($object instanceof CalculateSquare) {
echo 'Объект реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare() .
', это объект ' . get_class($objects[$key]) . ' класса.';
echo '<br>';
} else {
echo 'Объект класса ' . get_class($objects[$key]) . ' не реализует интерфейс CalculateSquare.';
}
}
По самому заданию - всё сделано хорошо. Только метод className() у вас везде одинаковый, да и в общем-то лишний. Но хорошо, что вы разобрались как это в целом работает :)
Я правильно полял , что интерфейс просто обязывает класс, реализующий интерфейс, содержать определенные методы , описаные в интерфейсе. Типа как конструктор , который обязывает дать имя котику (как пример в прошлых уроках)
"Через интерфейс мы можем изменять внутреннее состояние объекта, добиться от него каких-то действий, или получить от него что-то." - это определение из раздела "Объектно-ориентированный подход в PHP" который идет чуть позже , очень сильно облегчил понимание))
<?php
interface CalculateSquare{
public function calculateSquare():float;
}
class Rectangle{
private $x;
private $y;
public function __construct(float $x, float $y)
{
$this->x= $x;
$this->y= $y;
}
public function calculateSquare():float{
return $this->x*$this->y;
}
}
class Square implements CalculateSquare {
private $x;
public function __construct(float $x)
{
$this->x = $x;
}
public function calculateSquare():float{
return $this->x ** 2;
}
}
class Circle implements CalculateSquare {
const PI = 3.1416;
private $r;
public function __construct(float $r)
{
$this->r = $r;
}
public function calculateSquare():float{//Для того, чтобы обратиться к константе, нужно использовать конструкцию self::ИМЯ_КОНСТАНТЫ,
return self::PI * ($this->r ** 2);//или ИмяКласса::ИМЯ_КОНСТАНТЫ. Ключевое слово self – это обращение к текущему классу
}
}
$objects = [
new Square(5),
new Rectangle(2,4),
new Circle(5)
];
foreach ($objects as $object){
if ($object instanceof CalculateSquare){
echo 'Объект реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare() . '. Класс ' . get_class($object);
echo '<br>';
}
else {
echo 'Объект класса ' . get_class($object) . ' не реализует интерфейс CalculateSquare.';
echo '<br>';
}
}
<?php
class Rectangle implements CalculateSquare
{
private $x;
private $y;
public function __construct(float $x, float $y)
{
$this->x = $x;
$this->y = $y;
}
public function calculateSquare(): float
{
return $this->x * $this->y;
}
}
class Square implements CalculateSquare
{
private $x;
public function __construct(float $x)
{
$this->x = $x;
}
public function calculateSquare(): float
{
return $this->x ** 2;
}
}
class Circle
{
const PI = 3.1416;
private $r;
public function __construct(float $r)
{
$this->r = $r;
}
public function calculateSquare(): float
{
return self::PI * ($this->r ** 2);
}
}
$circle1 = new Circle(2.5);
//var_dump($circle1 instanceof CalculateSquare);
interface CalculateSquare
{
public function calculateSquare(): float;
}
$objects = [
new Square(5),
new Rectangle(2, 4),
new Circle(5)
];
foreach ($objects as $object) {
if ($object instanceof CalculateSquare) {
echo 'Object of class ' . get_class($object) . ' implements an Interface. Square is: ' . $object->calculateSquare() . "\n";
} else {
echo 'Object of class ' . get_class($object). ' doesn\'t implements an Interface. Square is: ' . $object->calculateSquare() . "\n";
}
}
Есть несколько вопросов:
1) почему я не могу использовать для вывода конструкцию
echo "Object of class {get_class($object)} implements an Interface. Square is: {$object->calculateSquare()} \n";
Выдает ошибку
Recoverable fatal error: Object of class Square could not be converted to string
при этом при проверке
echo gettype(get_class($object));
выдает string
2) При создании массива $objects используем []. Я чаще наблюдала массивы в (), и PHPStorm тоже создает с круглыми скобками. В чем разница и какие аргументы есть при выборе?
{get_class($object)} - так внутри строки не распарсится. Нельзя функции прямо там вызывать. Парится переменная $object, которую к строке привести не получается, вот и ругается. А вообще не надо использовать такой способ. Или используйте конкатенацию строк с кодом, либо используйте sprintf.
Современный стандарт PSR диктует правило короткого синтаксиса
В программировании зачастую требуется проверить, что перед нами сейчас какой-то конкретный тип объектов, то есть что перед нами экземпляр какого-то класса, либо что этот объект реализует какой-то интерфейс.
Домашнее задание легкое, чисто семантически все вроде пока просто и понятно. Но пример использования интерфейсов - чисто академический. Поэтому, хотелось бы каких-то практических жизненных примеров из реальных реализаций задач, как раз вот этих конкретных "зачастую", чтобы понимать - в каких задачах это уместно/необходимо, в каких - нет.
Здравствуйте, уважаемый Артём!
Сразу предупрежу, поднял homestead на vagrant,там внутри работает php v7.4: vagrant@homestead:~$ php --version
PHP 7.4.4 (cli) (built: Mar 20 2020 13:47:45) ( NTS ),
поэтому у всех свойств классов указаны модификаторы типа.
Так будет правильнее!
<?php
interface CalculateSquare
{
public function calculateSquare(): float;
}
class Circle implements CalculateSquare
{
const PI = 3.1416;
private float $r;
public function __construct(float $r)
{
$this->r = $r;
}
public function calculateSquare(): float
{
return self::PI * ($this->r ** 2);
}
}
class Rectangle
{
private float $x;
private float $y;
public function __construct(float $x, float $y)
{
$this->x = $x;
$this->y = $y;
}
public function calculateSquare(): float
{
return $this->x * $this->y;
}
}
class Square implements CalculateSquare
{
private float $x;
public function __construct(float $x)
{
$this->x = $x;
}
public function calculateSquare(): float
{
return $this->x ** 2;
}
}
$objects = [
new Square(5),
new Rectangle(2, 4),
new Circle(5)
];
//var_dump($objects);
foreach ($objects as $object) {
if ($object instanceof CalculateSquare) {
echo 'Объект класса ' . get_class($object) . ' реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare();
echo '<br>';
} else {
echo 'Объект класса ' . get_class($object) . ' не реализует интерфейс CalculateSquare.';
echo '<br>';
}
}
<?php
interface CalculateSquare
{
public function calculateSquare():float;
}
class Circle implements CalculateSquare
{
const PI = 3.1416;
private $r;
public function __construct(float $r)
{
$this->r=$r;
}
public function calculateSquare():float
{
return self::PI*($this->r**2);
}
}
class Rentagle implements CalculateSquare
{
private $x;
private $y;
public function __construct(float $x, float $y)
{
$this->x=$x;
$this->y=$y;
}
public function calculateSquare():float
{
return $this->y*$this->y;
}
}
class Square implements CalculateSquare
{
private $x;
public function __construct(float $x)
{
$this->x=$x;
}
public function calculateSquare():float
{
return $this->x **2;
}
}
$objects= [
new Square(5),
new Rentagle(2,4),
new Circle(5)
];
foreach($objects as $object){
if($object instanceof CalculateSquare){
echo 'Объект реализует интерфейс CalculateSquare. Площадь: '.$object->calculateSquare();
echo ' Относится к:'.get_class($object);
echo '</br>';
}
}
Интерфейсы для склеротиков? Ведь если убрать проверку на интерфейс из цикла, то все площади посчитаются исправно. Вне зависимости продекларирована приверженность к интерфейсу или нет.
P.S. это конечно шутка юмора - видимо в больших или огромных проектах интерфейсы возможно полезны для унификации и стандартизации. Но тогда должны быть подходы (способы), строго декларирующие использование и сами решения?
Возможно это развитие идеи абстрактных классов, ведь в PHP нельзя наследоваться от нескольких классов сразу, как в других языках, а указать несколько интерфейсов можно.
foreach($objects as $object) {
if($object instanceof CalculateSquare) {
echo 'Объект реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare() . ' - это объект класса ' . get_class($object);
echo '</br>';
} else {
echo 'Объект класса ' . get_class($object) . ' не реализует интерфейс CalculateSquary!';
echo '</br>';
}
}
RESULT:
Объект реализует интерфейс CalculateSquare. Площадь: 9 - это объект класса Square
Объект класса Rectangle не реализует интерфейс CalculateSquary!
Объект реализует интерфейс CalculateSquare. Площадь: 113.0976 - это объект класса Circle
<?php
interface CalculateSquare
{
public function calculateSquare():float;
}
class Rectangle
{
private $x;
private $y;
public function __construct(float $x, float $y)
{
$this->x = $x;
$this->y = $y;
}
public function calculateSquare():float
{
return $this -> x * $this -> y;
}
}
class Square implements CalculateSquare
{
private $x;
public function __construct(float $x)
{
$this->x = $x;
}
public function calculateSquare():float
{
return $this->x ** 2;
}
}
class Circle implements CalculateSquare
{
const PI = 3.1416;
private $r;
public function __construct(float $r)
{
$this->r = $r;
}
public function calculateSquare():float
{
return self::PI * ($this->r ** 2);
}
}
$objects = [
new Square(5),
new Rectangle(2,4),
new Circle(5)
];
foreach ($objects as $object) {
if ($object instanceof CalculateSquare){
echo 'Этот объект реализует интерфеёс Calculate. Объект класса '.get_class($object).'. Площадь: '. $object->calculateSquare().'.';
echo '<br/>';
} else {
echo 'Объект класса '.get_class($object).' не реализует интерфейс CalculateSquare.';
echo '<br/>';
}
}
get_class() - возвращает название класса, экземпляром которого является объект. Если переменная не ссылается на объект get_class() возвращает false. Начиная с версии PHP 7.2.0 объекту запрещено явно передавать значение NULL, это приведёт к ошибке уровня E_WARNING.
В ходе выполнения домашнего задания PHPStorm пожаловался на одну ошибку: Constant 'PI' not found in
Я так и не понял, как её решить, а так всё работает.
get_class ([ object $object ] ) : string
/*Возвращает имя класса, экземпляром которого является объект object.*/
Выполнила следующие пункты упражнения:
foreach ($objects as $object) {
if ($object instanceof CalculateSquare)
{
echo 'Объект реализует интерфейс CalculateSquare.
Площадь: ' . $object->calculateSquare() .
'. Объект относится к классу: ' . get_class($object) ;
echo '<br>';
}
else
{
echo 'Объект класса '. get_class($object) .
' не реализует интерфейс CalculateSquare.';
}
}
Если убрать из класса Circle упоминание о том, что он реализует этот интерфейс, то вывод следующий: Объект реализует интерфейс CalculateSquare. Площадь: 25. Объект относится к классу: Square
Объект реализует интерфейс CalculateSquare. Площадь: 8. Объект относится к классу: Rectangle
Объект класса Circle не реализует интерфейс CalculateSquare.
foreach ($objects as $object){
if($object instanceof CalculateSquare){
echo 'Объект реализует метод CalculateSquare и его площадь равна: ' . $object->calculateSquare();
echo '<br>';
echo 'А, и еще он принадлежит к классу ' . get_class($object) . '.';
echo '<br>';
}
else{
?>
<p style="color: red">Объект класса <?= get_class($object)?> не реализует интерфейс CalculateSquare.</p>
<?php
}
}
я так и не понял зачем это нужно, зачем нужны интерфейсы, зачем нам проверять реализует ли класс интерфейс, по логике это само собой разумеется, если мы пишем классы которые имеют методы для вычисления площади фигур, естественно мы должны эти методы реализовать.
Или пример не подходящий или же я ничего не понял.
Чёт не думал, что домашки надо выкладывать. Всё заработало, но вопрос остался в связи с новой версией пхп, и того, что технические данные пока не укладываются в голове. Вот собственно вопрос:
Замечание: Начиная с PHP 7.2.0, явная передача NULL в object запрещена. Параметр все еще опциональный и вызов get_class() без этого параметра внутри класса будет работать, но явная передача NULL теперь приведет к ошибке уровня E_WARNING.
Куда и какой параметр и для чего совать?
Вот домашка:
<?php
interface CalculateSquare
{
public function getName(): string;
public function calculateSquare(): float;
}
class Rectangle implements CalculateSquare
{
private $x;
private $y;
private $name;
public function __construct(float $x, float $y, string $name)
{
$this->x = $x;
$this->y = $y;
$this->name = $name;
}
public function calculateSquare() : float
{
return $this->x * $this->y;
}
public function getName(): string
{
return $this->name;
}
}
class Square implements CalculateSquare
{
private $x;
private $name;
public function __construct(float $x, string $name)
{
$this->x = $x;
$this->name = $name;
}
public function calculateSquare(): float
{
return $this->x ** 2;
}
public function getName(): string
{
return $this->name;
}
}
class Circle
{
const PI = 3.1416;
private $r;
private $name;
public function __construct(float $r, string $name)
{
$this->r = $r;
$this->name = $name;
}
public function calculateSquare(): float
{
return self::PI * ($this->r ** 2);
}
public function getName(): string
{
return $this->name;
}
}
//$round1 = new Circle(3);
$square1 = new Square(6, 'Квадрат');
$rectangle1 = new Rectangle(4, 3, 'Прямоугольник');
$objects = [
new Rectangle(5, 4, 'Прямоугольник'),
new Square(6, 'Квадрат'),
new Circle(7, 'Круг')
];
foreach($objects as $object) {
if ($object instanceof CalculateSquare) {
echo "Объект '" . $object->getName() . '\', класса (' . get_class($object) . ") реализует интерфейс CalculateSquare. \nПлощадь: " . $object->CalculateSquare() . "\n";
} else {
echo 'Безымянный объект принадлежит классу ' . get_class($object) . ', и интерфейс CalculateSquad не реализует, мать его так!';
}
echo "\n";
}
echo var_dump(get_class($rectangle1));
echo var_dump(get_class($square1));
По поводу вопроса - это из документации на php.net по get_class. Как я понял, в новом пхп get_class не будет выдавать значения, если его не поместить описания внутрь класса
По поводу задания: "Безымянный объект" - это пришлось написать, так как я попробовал в интерфейс положить 2 функции, одна из которых говорит, о каком объекте идёт речь, когда считается площадь. Но, так как в последнем классе, согласно заданию, я отключил реализацию интерфейса, то и представиться этот объект не мог, поэтому он "безымянный", но имеет называние класса)
Ребят, объясните что здесь не так:
class Circle {
private $r;
public function __construct(float $r) {
$this->r = $r;
}
public function calculateSquare(): float {
$pi = 3.1416;
return $pi * ($this->r ** 2);
}
}
$circle = new Circle(2.5);
//Проверяем, является ли объект $circle экземпляром класса Circle:
var_dump($circle instanceof Circle); // true
//Создали интерфейс:
interface CalculateSquare {
public function calculateSquare(): float;
}
echo '<br>';
//Проверяем, является ли $circle объектом, класс которого
//реализует интерфейс CalculateSquare:
var_dump($circle instanceof CalculateSquare); // false
Здесь выдает false, а должен быть true.
Оформляйте код (в редакторе комментариев самая первая кнопка).
Нажмите на карандашик и поправьте, пожалуйста. А потом ответьте мне на этот комментарий. Проверю после этого.
Нужно оформить код в комментарии (в редакторе комментариев самая первая кнопка).
Нажмите на карандашик и поправьте ваш комментарий, пожалуйста. А потом ответьте мне на этот комментарий. После этого проверю вашу домашнюю работу и отвечу на вопросы.
if ($object instanceof CalculateSquare) { //Срабатывает проверка: Теперь мы перед тем как попросить какой-либо объект посчитать свою площадь, можем проверить, есть ли у него такой метод, то есть, реализует ли он соответствующий интерфейс. Также можно проверять на класс SquareFigure и так далее
echo 'Это объект '. get_class($object) . ' класса. '.'Объект реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare();
echo '<br>';
} else {
echo 'Объект класса ' . get_class($object) . ' не реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare();
echo '<br>';
}
<?php
class Rectangle implements CalculateSquare
{
private $x;
private $y;
public function __construct(float $x, float $y)
{
$this->x = $x;
$this->y = $y;
}
public function calculateSquare(): float
{
return $this->x * $this->y;
}
}
class Square implements CalculateSquare
{
private $x;
public function __construct(float $x)
{
$this->x = $x;
}
public function calculateSquare(): float
{
return $this->x ** 2;
}
}
class Circle implements CalculateSquare
{
const PI = 3.1416;
private $r;
public function __construct(float $r)
{
$this->r = $r;
}
public function calculateSquare(): float
{
return self::PI * ($this->r ** 2);
}
}
interface CalculateSquare
{
public function calculateSquare(): float;
}
$circle1=new Circle(2.5);
var_dump($circle1 instanceof Circle);
$circle1=new Circle(2.5);
var_dump($circle1 instanceof Rectangle);
$circle1=new Circle(2.5);
var_dump($circle1 instanceof CalculateSquare);
echo '<br>';
$objects = [
new Square(5),
new Rectangle(2,4),
new Circle(5)
];
foreach ($objects as $object) {
if ($object instanceof CalculateSquare) {
echo 'Объект реализует интерфейс CalculateSquare. Относится к классу ' . get_class($object) . '. Площадь: ' . $object->calculateSquare();
echo '<br>';
} else {
echo 'Объект класса ' . get_class($object) . 'не реализует интерфейс CalculateSquare.';
}
}
Результат:
Объект реализует интерфейс CalculateSquare. Относится к классу Square. Площадь: 25
Объект реализует интерфейс CalculateSquare. Относится к классу Rectangle. Площадь: 8
Объект реализует интерфейс CalculateSquare. Относится к классу Circle. Площадь: 78.54
Добрый день Артём, метод get_class() возвращает имя класса, но вроде бы есть альтернативный вывод имени класса что-то вроде self::class или self::ИмяКласса, или я что-то путаю? Спасибо.
$objects = [
new Circle(6),
new Square(4),
new Rectangle(4,5),
];
foreach ($objects as $object) {
if ($object instanceof CalculateArea) {
echo 'Объект класса '.get_class($object).' реализует интерфейс CalculateArea. Его площадь: '.$object->calculateArea().'<br>';
}else{
echo 'Объект класса '.get_class($object).' не реализует интерфейс CalculateArea.<br>';
}
echo $object::class;
}
Пробую вот эту реализацию вывода имени класса echo $object::class; получаю ошибку
Вот такая ошибка выходит: Fatal error: Dynamic class names are not allowed in compile-time ::class fetch in D:\OSPanel\domains\test2\public_html\index.php on line 213
То что было сделано в уроке с помощью интерфейсов, можно же было сделать с помощью абстрактного класса(хотя это тоже из области полиморфизма), например так:
Есть абстрактный класс Shape с абстрактным методом вычисления площади, от которого наследуются классы Circle, Square, Rectangle и каждый из наследников реализует свой метод вычисления площади. И так же можно насоздавать массив объектов и проверять, является ли каждый из них объектом Shape, если да - выводить результат вычисления площади.
Т.е. через наследование реализовано то же самое, что было реализовано через интерфейс. Так если я прав, в чем преимущество использования интерфейса? Почему тут был применен именно интерфейс?
Важно(хотелось бы на будущее) понимать - когда прямо необходимо использовать интерфейс. По крайней мере, на этом примере - не очень понятно.
Да, вы правильно поняли, это можно было бы сделать и с помощью абстрактного класса.
Но у них разное предназначение. Интерфейс нужен только для того, чтобы его реализовывать (например метод для вычисления площади, как в нашем случае). Абстрактный класс нужен для того чтобы частично реализовать какую-то логику в нем, а частично - заставить реализовать в отдельных дочерних классах.
Дальше будут примеры с абстрактным контроллером, будет понятнее.
Фух, ну и пот. Вот вариант домашки:
Нормально, только
не нужно нигде - оно ведь нигде не используется. К тому же вызов get_class() без аргумента приведет к ошибке. Поправьте, пожалуйста :)
Пересмотрел код, участки вида:
оказались бессмыслены, их нужно просто удалить. Отредактировал, проверьте пожалуйста. Спасибо за подсказку)
Теперь отлично!
Не торопитесь и всё будет супер-пупер ;)
Как-то так.
Разве работает?
Ну вот так работает. Я просто выложил только домашку, без кода скопированного из урока.
Да нет, это я понял. Странно что работает функция get_Class - это видимо какой-то баг в PHP. Нужно использовать get_class - все в нижнем регистре.
Отлично!
Супер!
Отлично =)
Супер!
Отлично!
Вроде так.
Все ок
Хорошо, только не стоило убирать расчет площади.
Отлично!
Домашка :))
Супер!
Отлично!
Познакомьтесь самостоятельно с функцией get_class().
Дополните информацию об объекте, для которого считается площадь – пишите что это объект такого-то класса.
Для объектов, которые не реализуют интерфейс CalculateSquare пишите:
Объект класса ТУТ_НАЗВАНИЕ_КЛАССА не реализует интерфейс CalculateSquare.
Отлично!
Отлично!
Отлично!
Домашка:
Отлично
Отлично
Вопрос по поводу типизации данных. PhpStorm выдает ошибку если указывать эту строгую типизацию.
Насколько это грозит последствиями если ее не указывать?
P.S. Новое для себя открыл, крутое выражение возведение в степень **2.
По коду - ок. Шторм правильно всё говорит, если ожидаете целочисленное, то и передавать нужно целочисленное. Лучше сейчас использовать strict_types=1 уже.
Дополните информацию об объекте, для которого считается площадь – пишите что это объект такого-то класса.
Для объектов, которые не реализуют интерфейс CalculateSquare пишите:
Объект класса ТУТ_НАЗВАНИЕ_КЛАССА не реализует интерфейс CalculateSquare.
Отлично!
Ок!
Ок!
По самому заданию - всё сделано хорошо. Только метод className() у вас везде одинаковый, да и в общем-то лишний. Но хорошо, что вы разобрались как это в целом работает :)
Отлично
Отлично
Отлично
Отлично
Отлично
Отлично!
Отлично!
Отлично
Я правильно полял , что интерфейс просто обязывает класс, реализующий интерфейс, содержать определенные методы , описаные в интерфейсе. Типа как конструктор , который обязывает дать имя котику (как пример в прошлых уроках)
Всё верно описали, но аналогия с конструктором лишняя, не очень подходящий пример.
"Через интерфейс мы можем изменять внутреннее состояние объекта, добиться от него каких-то действий, или получить от него что-то." - это определение из раздела "Объектно-ориентированный подход в PHP" который идет чуть позже , очень сильно облегчил понимание))
Там под интерфейсом подразумевается просто набор публичных методов. Не то, что здесь описывается с помощью слова interface :)
Домашка Урок: 4 (Интерфейсы)
А почему это свойство public?
Отлично
Отлично. Только отступы после else поехали. Для формирования кода используйте кнопку в редакторе комментариев, слева вверху.
Отлично!
Супер!
Отлично
ДЗ
Отлично
Отлично
Отлично!
Есть несколько вопросов:
1) почему я не могу использовать для вывода конструкцию
Выдает ошибку
при этом при проверке
выдает string
2) При создании массива $objects используем []. Я чаще наблюдала массивы в (), и PHPStorm тоже создает с круглыми скобками. В чем разница и какие аргументы есть при выборе?
Вместо
Второй вариант считается устаревшим.
Поняла, спасибо!
У вас опечатка в разделе "Интерфейсы":
"Окей, разобрались с константами и имеем в итоге 3 объекта, описывающих геометрические фигуры и реализацию для вычисления их площадей."
Вместо "3 объекта" - "3 класса".
Отличное замечание, спасибо!
Отлично
Отлично
Отлично
является объектом класса
В остальном - отлично
Отлично
Отлично
Супер!
Отлично
Домашка:
Отлично
Отлично
Домашка:
Отлично
Супер!
Отлично
Домашнее задание легкое, чисто семантически все вроде пока просто и понятно. Но пример использования интерфейсов - чисто академический. Поэтому, хотелось бы каких-то практических жизненных примеров из реальных реализаций задач, как раз вот этих конкретных "зачастую", чтобы понимать - в каких задачах это уместно/необходимо, в каких - нет.
Примеры будут в дальнейшем
Отлично
Отлично
Очепятка :D
а также создадим у методы
Спасибо, исправил
Отлично!
Домашка
Супер!
Отлично
Здравствуйте, уважаемый Артём!
Сразу предупрежу, поднял homestead на vagrant,там внутри работает php v7.4:
vagrant@homestead:~$ php --version
PHP 7.4.4 (cli) (built: Mar 20 2020 13:47:45) ( NTS ),
поэтому у всех свойств классов указаны модификаторы типа.
Так будет правильнее!
Отлично! За типы свойств большой плюс! Нужно тоже доработать урок.
Отлично!
Отлично
Отлично
Отлично)
Интерфейсы для склеротиков? Ведь если убрать проверку на интерфейс из цикла, то все площади посчитаются исправно. Вне зависимости продекларирована приверженность к интерфейсу или нет.
P.S. это конечно шутка юмора - видимо в больших или огромных проектах интерфейсы возможно полезны для унификации и стандартизации. Но тогда должны быть подходы (способы), строго декларирующие использование и сами решения?
Возможно это развитие идеи абстрактных классов, ведь в PHP нельзя наследоваться от нескольких классов сразу, как в других языках, а указать несколько интерфейсов можно.
В том числе. Но в первую очередь - это гарантия реализации методов.
вот что получилось:
Отлично
HomeWork:
RESULT:
Объект реализует интерфейс CalculateSquare. Площадь: 9 - это объект класса Square
Объект класса Rectangle не реализует интерфейс CalculateSquary!
Объект реализует интерфейс CalculateSquare. Площадь: 113.0976 - это объект класса Circle
Ок. Зачем только два раза код написали?)
get_class() - возвращает название класса, экземпляром которого является объект. Если переменная не ссылается на объект get_class() возвращает false. Начиная с версии PHP 7.2.0 объекту запрещено явно передавать значение NULL, это приведёт к ошибке уровня E_WARNING.
В ходе выполнения домашнего задания PHPStorm пожаловался на одну ошибку: Constant 'PI' not found in
Я так и не понял, как её решить, а так всё работает.
Всё отлично. Шторм скорее всего малость поехал крышей. Попробуй перезапустить его.
Хорошо
Опять же спасибо вашим урокам! Если бы не вы, пользовался бы я устаревшим объявлением массива
Отлично
Отлично
внесенные изменения
почему в примерах документации используются запятые, а не точка (echo "Меня зовут " , get_class($this) , "\n";)
Через точку происходит конкатенация строки. А конструкция echo поддерживает вывод значений, перечисленных через запятую
Супер!
Мой пример
Отлично
Отлично
Отлично
Выполнила следующие пункты упражнения:
Если убрать из класса Circle упоминание о том, что он реализует этот интерфейс, то вывод следующий:
Объект реализует интерфейс CalculateSquare. Площадь: 25. Объект относится к классу: Square
Объект реализует интерфейс CalculateSquare. Площадь: 8. Объект относится к классу: Rectangle
Объект класса Circle не реализует интерфейс CalculateSquare.
Ок. А что с форматированием вдруг стало? Делайте отступы и переносы как в уроках. Для этого в шторме можно нажать Ctrl+Alt+L
Отлично
Спасибо за урок!
Отлично
я так и не понял зачем это нужно, зачем нужны интерфейсы, зачем нам проверять реализует ли класс интерфейс, по логике это само собой разумеется, если мы пишем классы которые имеют методы для вычисления площади фигур, естественно мы должны эти методы реализовать.
Или пример не подходящий или же я ничего не понял.
Пример учебный, просто чтобы показать как интерфейсы работают. Практическое применение на более подходящих примерах будет рассмотрено далее по курсу.
Во-первых, подобное условие стоит записывать как
Ну а во-вторых, тут будет достаточно простого else без каких-либо дополнительных условий.
Красота!
Все правильно?
имена классов и интерфейсов пишутся с большой буквы
Лишний перенос строки
это зачем?
Объектов несколько, поэтому называть нужно $objects.
Проблема с форматированием. Делайте отступы и переносы как в уроках. Для этого в шторме можно нажать Ctrl+Alt+L
Чёт не думал, что домашки надо выкладывать. Всё заработало, но вопрос остался в связи с новой версией пхп, и того, что технические данные пока не укладываются в голове. Вот собственно вопрос:
Куда и какой параметр и для чего совать?
Вот домашка:
Я не понял вашего вопроса. Можете пример скинуть?
По домашке всё отлично кроме вот этой формулировки: "Безымянный объект" - что это вообще такое?
По поводу вопроса - это из документации на php.net по get_class. Как я понял, в новом пхп get_class не будет выдавать значения, если его не поместить описания внутрь класса
По поводу задания: "Безымянный объект" - это пришлось написать, так как я попробовал в интерфейс положить 2 функции, одна из которых говорит, о каком объекте идёт речь, когда считается площадь. Но, так как в последнем классе, согласно заданию, я отключил реализацию интерфейса, то и представиться этот объект не мог, поэтому он "безымянный", но имеет называние класса)
Теперь понял)
get_class не будет работать, если вместо объекта передать туда null
Ребят, объясните что здесь не так:
class Circle {
private $r;
}
$circle = new Circle(2.5);
//Проверяем, является ли объект $circle экземпляром класса Circle:
var_dump($circle instanceof Circle); // true
//Создали интерфейс:
interface CalculateSquare {
public function calculateSquare(): float;
}
echo '<br>';
//Проверяем, является ли $circle объектом, класс которого
//реализует интерфейс CalculateSquare:
var_dump($circle instanceof CalculateSquare); // false
Здесь выдает false, а должен быть true.
Или я не прав.
Оформляйте код (в редакторе комментариев самая первая кнопка).
Нажмите на карандашик и поправьте, пожалуйста. А потом ответьте мне на этот комментарий. Проверю после этого.
foreach ($objects as $object) {
if ($object instanceof CalculateSquare) {
echo 'Объект класса ' . get_class($object) . ' реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare();
echo '<br>';
}else echo 'Объект класса ' . get_class($object) . ' не реализует интерфейс CalculateSquare. Площадь: ' . $object->calculateSquare(); echo '<br>';
}
Нужно оформить код в комментарии (в редакторе комментариев самая первая кнопка).
Нажмите на карандашик и поправьте ваш комментарий, пожалуйста. А потом ответьте мне на этот комментарий. После этого проверю вашу домашнюю работу и отвечу на вопросы.
Всегда используйте фигурные скобки для блоков if-else.
Проблема с форматированием. Делайте отступы и переносы как в уроках. Для этого в шторме можно нажать Ctrl+Alt+L
С логикой всё ок
Отлично
Отлично
Добрый день!
Отлично
Результат:
Объект реализует интерфейс CalculateSquare. Относится к классу Square. Площадь: 25
Объект реализует интерфейс CalculateSquare. Относится к классу Rectangle. Площадь: 8
Объект реализует интерфейс CalculateSquare. Относится к классу Circle. Площадь: 78.54
Отлично
Супер!
Добрый день Артём, метод get_class() возвращает имя класса, но вроде бы есть альтернативный вывод имени класса что-то вроде self::class или self::ИмяКласса, или я что-то путаю? Спасибо.
Да, можно использовать даже $var::class, если вы точно знаете, что в переменной находится объект
Пробую вот эту реализацию вывода имени класса echo $object::class; получаю ошибку
Что за ошибка?
Вот такая ошибка выходит: Fatal error: Dynamic class names are not allowed in compile-time ::class fetch in D:\OSPanel\domains\test2\public_html\index.php on line 213
Извините что ввел вас в заблуждение, с переменной всё-таки нельзя ::class писать
Отлично
То что было сделано в уроке с помощью интерфейсов, можно же было сделать с помощью абстрактного класса(хотя это тоже из области полиморфизма), например так:
Есть абстрактный класс Shape с абстрактным методом вычисления площади, от которого наследуются классы Circle, Square, Rectangle и каждый из наследников реализует свой метод вычисления площади. И так же можно насоздавать массив объектов и проверять, является ли каждый из них объектом Shape, если да - выводить результат вычисления площади.
Т.е. через наследование реализовано то же самое, что было реализовано через интерфейс. Так если я прав, в чем преимущество использования интерфейса? Почему тут был применен именно интерфейс?
Важно(хотелось бы на будущее) понимать - когда прямо необходимо использовать интерфейс. По крайней мере, на этом примере - не очень понятно.
Да, вы правильно поняли, это можно было бы сделать и с помощью абстрактного класса.
Но у них разное предназначение. Интерфейс нужен только для того, чтобы его реализовывать (например метод для вычисления площади, как в нашем случае). Абстрактный класс нужен для того чтобы частично реализовать какую-то логику в нем, а частично - заставить реализовать в отдельных дочерних классах.
Дальше будут примеры с абстрактным контроллером, будет понятнее.
Отлично
Отлично
Сделал
Отлично
Отлично