[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Суть интерфейсов и абстрактных классов
Страницы: 1, 2, 3
user_name
Допустим у меня есть абстрактный класс и в нем абстрактный метод. Дочерние классы обязаны содержать реализацию этого абстрактного метода. Но что если в каком то из классов мне этот метод не нужен? Мне его делать пустым? Я запутался хд
twin
user_name
Цитата
Мне его делать пустым?
Да.

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
user_name
twin
Цитата
Да.

А что у если у меня их нимало, каждый раз писать что то вроде этого
function name() {}
где то тут сказали что это не красиво.
twin
Се ля ви, ничего не поделаешь.

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
mvg
Цитата (user_name @ 24.12.2014 - 17:56)
Допустим у меня есть абстрактный класс и в нем абстрактный метод. Дочерние классы обязаны содержать реализацию этого абстрактного метода. Но что если в каком то из классов мне этот метод не нужен? Мне его делать пустым? Я запутался хд

Ситуаций когда наследуя абстрактный класс, абстрактная функция остается опять абстрактной (не реализуется) быть не должно. Если вдруг получилось что пустая функция снова пустая, то надо идти смотреть правильно ли организованны классы (объектно ориентированный дизайн редактировать) и все ли в порядке с их иерархией и правильно ли наследуется и что можно изменить чтобы унаследовать класс и избежать переопределение пустой(абстрактной) функции. Все абстрактные функции должны быть реализованы в наследуемом классе и не быть снова абстрактными (пустыми).
twin
mvg
Вообще не факт. На примере того же Yii: есть абстрактный класс CModel и хоть ты тресни, но во всех моделях (а они по архитекткре должны от него наследоваться) придется реализовывать метод attributeNames(). Нужен он или не нужен. И если он не нужен, то будет пустым.

И что, по твоей логике нужно перепиливать фреймворк?

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Arh
Цитата
Но что если в каком то из классов мне этот метод не нужен? Мне его делать пустым? Я запутался хд

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

Мне вот интересно если сделать абстрактный класс, у которого все методы будут абстрактными, будет ли разница если вместо этого класса сделать интерфейс, у которого по умолчанию все методы абстрактные? Если нет, тогда смысл в интерфейсах?
interface test {
function one();
function two();
}


abstract class test {
abstract function one();
abstract function two();
}


_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
mvg
Цитата (Michael @ 24.12.2014 - 17:07)
mvg, то мы говорили о методе С реализацией, просто там нет кода. Самый признак что надо класс объявлять абстрактным.

Michael, я говорил что если такой класс не обявить ключевым словом abstract то функция и класс тоже будут называться абстрактными. Т.е. объявлять не обязательно, важно понимать что такое абстрактная функция.

К примеру функция

protected function foo(){}


есть абстрактная и ничем не отличается от функции

protected abstract function foo(){}


по своему смыслу т.к. также является абстрактной.

Также и класс

class foo{
protected function foo(){}
}


есть абстрактным и ничем не отличается от класса

abstract class foo{
protected function foo(){}
}


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

class foo{
protected function foo(){}
}


class bar extended foo{}
class baz extended foo{}
class bak extended foo{}
class bal extended foo{}
class baf extended foo{}

класс foo является интерфейсом для классов которые его наследуют.

Я об этом говорил.
mvg
Цитата (Arh @ 24.12.2014 - 19:47)
Цитата
Но что если в каком то из классов мне этот метод не нужен? Мне его делать пустым? Я запутался хд

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

Мне вот интересно если сделать абстрактный класс, у которого все методы будут абстрактными, будет ли разница если вместо этого класса сделать интерфейс, у которого по умолчанию все методы абстрактные? Если нет, тогда смысл в интерфейсах?
interface test {
function one();
function two();
}


abstract class test {
abstract function one();
abstract function two();
}

Если класс использовать как интерфейс то разницы нет, если класс использовать в других качествах - разница появиться.

Если есть возможность то лучше оставить класс не переделывая в интерфейс потому что в классе можно определить переменные (свойства), а в интерфейсе нет.
mvg
Цитата (twin @ 24.12.2014 - 19:44)
mvg
Вообще не факт. На примере того же Yii: есть абстрактный класс CModel и хоть ты тресни, но во всех моделях (а они по архитекткре должны от него наследоваться) придется реализовывать метод attributeNames(). Нужен он или не нужен. И если он не нужен, то будет пустым.

И что, по твоей логике нужно перепиливать фреймворк?

Если гвозди забивать плоскогубцами то результат не будет отличаться от случае если гвозди забиты молотком, но гвозди надо забивать молотком!

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

Что касается функции attributeNames() то она задает правила для валидации и должен быть реализован чтобы правила валидации были заданы.

Таких вариантов при которых метод не нужен: не существует - он всегда нужен и его всегда нужно реализовывать, а если вы посчитали что метод не нужен - вперед "перепиливать" фреймворк потому что да, не реализованных и переопределенных абстрактными абстрактных методов быть не должно.

И еще - можно модель создавать унаследовав классы производные от CModel, а не сам CModel. Возможно так можно опустить функцию attributeNames().
twin
mvg
Наверное ты прав. Все никак не могу принять, что в ООП все нужно сначала усложнить, чтобы потом было проще. Единственно, что не так, так то, что метод attributeNames() применяется не для валидации, а для доступа к результатам модели. И если следовать принципам унификации, этот метод обязателен.

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
mvg
Цитата (twin @ 24.12.2014 - 20:47)
mvg
Наверное ты прав. Все никак не могу принять, что в ООП все нужно сначала усложнить, чтобы потом было проще. Единственно, что не так, так то, что метод attributeNames() применяется не для валидации, а для доступа к результатам модели. И если следовать принципам унификации, этот метод обязателен.

В комментариях к методу написано - задает правила для валидации. Короче возвращает массив с атрибутами класса. Есть отдельная пометка - если метод переопределен родителем, то надо объединять массивы в классе потомке. - так написано в комментариях к методу.

Усложнять тоже не надо. Надо чтобы все было красиво :-) - наверное для этого объектно ориентированный дизайн (OOD) начал развиваться.
Guest
interface ITest1 {}
interface ITest2

abstract class Test1{}
abstract class Test2()

class Test1 extends Test - один и только один можно наследовать класс
class Test1 implements ITest1, ITest2 - класс может выполнять несколько функций и является сколь угодно типизированным, естественно заставляют его реализовать методы

Абстрактный класс при правильном использовании позволяет сделать чистым код и реализовать безопасное программирование, например патттерн "Шаблонный метод"

abstract class TemplateMethod
{
public function exec()
{
$this->firstAlgoritm();
$this->secondAlgoritm();
}

// Обязываем дочерний класс реализовать первый алгоритм
abstract protected function firstAlgoritm();
// Обязываем дочерний класс реализовать второйалгоритм
abstract protected function secondAlgoritm();
}


Если дочерний класс имеет пустой метод алгоритма нарушение принципа Лисковой (метод должен принимать сигнатуру и отдавать данные заявленные из родительского класса) и стоит пересмотреть архитектуру или применять интерфейсы, которые можно имплементировать сколь угодно и раздельно к классам.
Guest
abstract class TemplateMethod
{
final public function exec()
{
$this->firstAlgoritm();
$this->secondAlgoritm();
}

// Обязываем дочерний класс реализовать первый алгоритм
abstract protected function firstAlgoritm();
// Обязываем дочерний класс реализовать второйалгоритм
abstract protected function secondAlgoritm();
}
twin
Цитата (mvg @ 24.12.2014 - 17:58)
Усложнять тоже не надо. Надо чтобы все было красиво :-) - наверное для этого объектно ориентированный дизайн (OOD) начал развиваться.

Ну это и есть усложнение кода. Да, для унификации, а как следствие, для упрощения последующих телодвижений. Вот к примеру мне было бы достаточно сделать так:
class PagesModel extends CModel
{
public function getContent($page)
{
return Yii::app()->db->createCommand()
->
select('m_title, m_keywords, m_description, text')
->
from('{{pages}}')
->
where('page = :page', array(':page' => $page))
->
queryRow();

}
}

но по правилам дизайна я должен делать так:
class PagesModel extends CModel
{
protected $row;

public function attributeNames()
{
return array(
'm_title' => $this->row['m_title'],
'm_keywords' => $this->row['m_keywords'],
'm_description' => $this->row['m_description'],
'text' => $this->row['text']
);

}

public function getContent($page)
{
$this->row = Yii::app()->db->createCommand()
->
select('m_title, m_keywords, m_description, text')
->
from('{{pages}}')
->
where('page = :page', array(':page' => $page))
->
queryRow();

}
}
Смысл этого демарша один - унифицировать обращение к модели. Оно помогает конечно, когда работает команда над валовым продуктом. Тут спору нет.

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Быстрый ответ:

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