я понял, наконец

Фанат

oncle terrible
Команда форума
интерфейс - это публичный контракт, смотрит наружу
абскласс - это прототип для имплементации, для внутреннего потребления
 

AmdY

Пью пиво
Команда форума
и тут приходит java 8 со своим default и static в интерфейсах и всё окончательно запутала.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
интерфейс - это публичный контракт, смотрит наружу
абскласс - это прототип для имплементации, для внутреннего потребления
Ты смотри, так еще и поймешь, почему final хорошо, и зачем composition over inheritance :)
Потом может и почему родные плейсхолдеры лучше эмулированных)
 

Фанат

oncle terrible
Команда форума
Ты смотри, так еще и поймешь, почему final хорошо, и зачем composition over inheritance :)
Потом может и почему родные плейсхолдеры лучше эмулированных)
про композишен кстати много где написано, а вот это я сразу полез себя проверить, но навскидку не нашёл.
везде технические детали реализации, вот как у @AmdY, а про суть никто не пишет
 

флоппик

promotor fidei
Команда форума
Партнер клуба
про композишен кстати много где написано, а вот это я сразу полез себя проверить, но навскидку не нашёл.
везде технические детали реализации, вот как у @AmdY, а про суть никто не пишет
на самом деле, у тебя буквально в соседней теме был пример про compostion over inheritance, где ты предлагал для своего дата-маппера наследоватся, чтоб перекрыть единственный метод и это очевидно неудобно. Очевидно, что нужно дать возможность компоновать с произвольными мапперами, которые будут просто поддерживать контракт.
 

Фанат

oncle terrible
Команда форума
Ну ясно, по теме короче никто не напишет. Видимо, не до всех эта мысль реально дошла, я первый :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Ну ясно, по теме короче никто не напишет. Видимо, не до всех эта мысль реально дошла, я первый :)
Это смотря что ты называешь внутренним употреблением, обычно так называют жидкости. :)

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

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

fixxxer

К.О.
Партнер клуба
По теме - на самом деле не совсем так, pure abstract class, например, выполняет роль интерфейса. (Вон в С++ интерфейсов вообще нет, например). И, да, абстрактный класс вполне может выполнять и обе эти две роли сразу.

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

Фанат

oncle terrible
Команда форума
По теме - на самом деле не совсем так, pure abstract class, например, выполняет роль интерфейса. (Вон в С++ интерфейсов вообще нет, например.)
Объясни?
Ну то есть зерно я в этом вижу, но скажем в пхп есть именно четкое разделение, исходя из предназначения.
И кстати проблема, которую в жабе пофиксили костылем с деофлтными методами, решается именно черезабастрактные классы.
 

fixxxer

К.О.
Партнер клуба
ну вот можно написать так
PHP:
abstract class Logger {
    abstract public function logError(string $message): void;
}
class SyslogLogger extends Logger {
    public function logError(string $message): void {
        syslog(LOG_ERR, $message);
    }
}
а можно так
PHP:
interface Logger {
    public function logError(string $message): void;
}
class SyslogLogger implements Logger {
    public function logError(string $message): void {
        syslog(LOG_ERR, $message);
    }
}
В чем разница?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Объясни?
Ну то есть зерно я в этом вижу, но скажем в пхп есть именно четкое разделение, исходя из предназначения.
На самом деле, нет. Это контракт и частичная имплементация как термины - они не связаны с языком. Ты можешь делать (и в пхп) контракты на абстрактных классах, например. Это будет менее удобно, но вполне реально, что они будут выполнять роль контракта, а не быть частичной реализацией. Duck typing например, позволяет иметь контракты в языках, где нет интерфейсов. Значит ли что там нельзя делать контракты? Конечно нет.
 

Фанат

oncle terrible
Команда форума
Разница в том что пример неправильный.
Должно быть
PHP:
interface LoggerInterface { // контракт наружу
    public function logError(string $message): void;
}
abstract class Logger { // прототип внутрь
    abstract public function logError(string $message): void;
}
class SyslogLogger extends Logger implements LoggerInterface{
    public function logError(string $message): void {
        syslog(LOG_ERR, $message);
    }
}
 
Последнее редактирование:

флоппик

promotor fidei
Команда форума
Партнер клуба
Значит, не наконец... :D
В твоем примере - два контракта, и ни одного прототипа.
 

Фанат

oncle terrible
Команда форума
Значит, не наконец... :D
В твоем примере - два контракта, и ни одного прототипа.
Лепил из того что было. Для случая вырожденного абстрактного примера контракт и прототип совпадают. В реальной жизни они разойдутся.
Но я могу добавить что-нибудь, чтобы шашечки.
 

Фанат

oncle terrible
Команда форума
PHP:
interface LoggerInterface { // для внешних клиентов
    public function logError(string $message): void;
}
abstract class Logger { // для потомков
    public function logError(string $message): void {
        fwrite($this->destination, $message);
    }
}
class ScreenLogger extends Logger implements LoggerInterface {
    public function __construct() {
        $this->destination = fopen("php://stdout", 'w');
    }
}
 

fixxxer

К.О.
Партнер клуба
PHP:
interface LoggerInterface { // для внешних клиентов
    public function logError(string $message): void;
}
abstract class Logger { // для потомков
    public function logError(string $message): void {
        fwrite($this->destination, $message);
    }
}
class ScreenLogger extends Logger implements LoggerInterface {
    public function __construct() {
        $this->destination = fopen("php://stdout", 'w');
    }
}
А почему implements LoggerInterface у ScreenLogger, а не у abstract Logger?
 
Сверху