чем?и тут приходит java 8 со своим default и static в интерфейсах и всё окончательно запутала.
Ты смотри, так еще и поймешь, почему final хорошо, и зачем composition over inheritanceинтерфейс - это публичный контракт, смотрит наружу
абскласс - это прототип для имплементации, для внутреннего потребления
про композишен кстати много где написано, а вот это я сразу полез себя проверить, но навскидку не нашёл.Ты смотри, так еще и поймешь, почему final хорошо, и зачем composition over inheritance
Потом может и почему родные плейсхолдеры лучше эмулированных)
на самом деле, у тебя буквально в соседней теме был пример про compostion over inheritance, где ты предлагал для своего дата-маппера наследоватся, чтоб перекрыть единственный метод и это очевидно неудобно. Очевидно, что нужно дать возможность компоновать с произвольными мапперами, которые будут просто поддерживать контракт.про композишен кстати много где написано, а вот это я сразу полез себя проверить, но навскидку не нашёл.
везде технические детали реализации, вот как у @AmdY, а про суть никто не пишет
Это смотря что ты называешь внутренним употреблением, обычно так называют жидкости.Ну ясно, по теме короче никто не напишет. Видимо, не до всех эта мысль реально дошла, я первый![]()
ну просто сорри, это ж реально очевидные вещи, о которых спорить смысла нет.Ну ясно, по теме короче никто не напишет. Видимо, не до всех эта мысль реально дошла, я первый![]()
ипубличный контракт
и пофиг какие там в каком языке программирования ключевые слова.прототип для имплементации
Объясни?По теме - на самом деле не совсем так, pure abstract class, например, выполняет роль интерфейса. (Вон в С++ интерфейсов вообще нет, например.)
abstract class Logger {
abstract public function logError(string $message): void;
}
class SyslogLogger extends Logger {
public function logError(string $message): void {
syslog(LOG_ERR, $message);
}
}
interface Logger {
public function logError(string $message): void;
}
class SyslogLogger implements Logger {
public function logError(string $message): void {
syslog(LOG_ERR, $message);
}
}
На самом деле, нет. Это контракт и частичная имплементация как термины - они не связаны с языком. Ты можешь делать (и в пхп) контракты на абстрактных классах, например. Это будет менее удобно, но вполне реально, что они будут выполнять роль контракта, а не быть частичной реализацией. Duck typing например, позволяет иметь контракты в языках, где нет интерфейсов. Значит ли что там нельзя делать контракты? Конечно нет.Объясни?
Ну то есть зерно я в этом вижу, но скажем в пхп есть именно четкое разделение, исходя из предназначения.
Разница в том что пример неправильный.В чем разница?
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);
}
}
Лепил из того что было. Для случая вырожденного абстрактного примера контракт и прототип совпадают. В реальной жизни они разойдутся.Значит, не наконец...
В твоем примере - два контракта, и ни одного прототипа.
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?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'); } }