.NET Fest: полная программа конференции на сайте. Присоединяйся к самому большому .NET ивенту
×Закрыть

Абстрактный класс и интерфейс :D

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

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

Формулировка — сравнить эти две вещи, и что от тебя ждут ответ на это, кажется абсурдом и отключает. Может нужно ходить регулярно на собеседования для поддержания формы?

LinkedIn

Лучшие комментарии пропустить

Работать и проходить собеседования — два разных занятия, требующих 2х разных, обычно не пересекающихся, наборов скилов.

Может нужно ходить регулярно на собеседования для поддержания формы?

Конечно нужно. Для поддержания себя в форме, выработки скила проходить собеседования и понимания того, что вообще на рынке происходит.

Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

В своё время проводил множество интервью. Вопрос, может и поднадоевший, но здорово выручает, если интервью начать прямо с него. Если человек не может на него внятно ответить — это отличный детектор, интервью можно сразу плавно и деликатно завершать.

в ц++ нет интерфейсов ))

То есть, если человек начал отвечать, можно уже завершать интервью ))

с джавой както все подзабыли, что интерфейс это вообще оригинальный паттерн...

Есть. Вот скажу, что это класс инттерфейс, значит он интерфейс. И вообще вот это объявление функции или переменной тоже интерфейс.

даже если у функции есть дефолтная имплементация

Да, почему нет?
Интерфейс — это то, что торчит наружу и за что можно дергать.

я ж не спорю. просто еще один аргумент к гибкости плюсов

Інтерфейс — декларація функціональних можливостей об’єкта.
Абстрактний клас — декларація базової структури об’єкта.
Між ними різниці майже немає. Все залежить від конкретної реалізації в мовах програмування.

Між ними різниці майже немає.

:D

Останніх декілька років програмую на TypeScript, то у ньому чітко розрізняється призначення між інтерфейсом й абстрактним класом (це якщо порівнювати, наприклад, з PHP). Інтерфейс незрівнянно частіше застосовується на практиці, ніж абстрактний клас.

Зверніть увагу на:
1. смисл ключових слів для інтерфейсу й абстрактного класу (implements, extends);
2. особливість використання модифікаторів доступу (private, protected, public).

Інтерфейси — імплементуються, абстрактні класи — розширюються, причому інтерфейси не мають сенсу з модифікаторами доступу private й protected (лише public).

Тобто, інтерфейси призначаються для «публічного» узгодження по типам даним й сигнатурі методів, тоді як абстрактні класи являють собою найбільш базову форму класу, призначену для розширення, де, окрім типів даних, може закладатись й поведінка методів.

В абстрактному класі модифікатори доступу private й protected можуть використовуватись саме через те, що в ньому вже закладено базову частину функціональності, яку можна повторно використовувати в дочірніх класах.

Якщо у вашому абстрактному класі усі члени публічні й не закладено жодної поведінки у методах — вам потрібен інтерфейс.

TypeScript, то у ньому чітко розрізняється призначення між інтерфейсом й абстрактним класом (це якщо порівнювати, наприклад, з PHP)
любопытства ради, можете аргументировано объяснить, почему, с Вашей точки зрения, в PHP это разделение не такое ясное как TypeScript? вот лично с моей колокольни они идентичны. ну разве что за исключением возможности в TypeScript объявлять поля на уровне интерфейса, что как по мне, наоборот еще больше создает путаницу

Усе просто: PHP — динамічно типізована мова програмування, тоді як TypeScript має статичну типізацію.

У TypeScript дуже часто використовуються інтерфейси, бо вони описують саме типи даних. А коли ближче працюєш з типами даних, то й чіткіше стає зрозуміло для чого це взагалі потрібно.

динамічно типізована мова програмування, тоді як TypeScript має статичну типізацію.
объясните как это влияет на понимание сущностей «абстрактный класс» и «интерфейс». как по мне статическая типизация в реальности ничем не помогает в понимании.
У TypeScript дуже часто використовуються інтерфейси, бо вони описують саме типи даних. А коли ближче працюєш з типами даних, то й чіткіше стає зрозуміло для чого це взагалі потрібно
а вот это однозначный минус для понимания. в TypeScript интерфейс часто служит тем что в других языках называют структурами. соотвественно ввиду того что одна сущность может исполнять две роли то однозначно потребуется больше когнитивных усилий. и еще больше схожести с абстрактным классом чем в PHP
объясните как это влияет на понимание сущностей «абстрактный класс» и «интерфейс». как по мне статическая типизация в реальности ничем не помогает в понимании.

Статична типізація в TypeScript передбачає явне вказування типу даних, на відміну від динамічної типізації в PHP. Що це за собою тягне? — Частіше фокусування уваги на типах даних і на їх відмінностях.

Грубо кажучи, через місяць-другий роботи на TypeScript, коли тобі приходиться писати інтерфейси значно частіше, ніж класи, в тебе вже вимальовується чітке розуміння «що таке інтерфейс», чому в інтерфейсі не можна писати тіла методів, і чому в інтерфейсі використовуються виключно публічні модифікатори доступу.

Ще одне доповнення до вищезазначеного мого опису відмінностей: інтерфейс — це «обрізана версія» абстрактного класу. Не пам’ятаю як в PHP, але в TypeScript ви можете позначати тип даних конкретної змінної через абстрактний клас, точно так само як це ви робите за допомогою інтерфейса.

Грубо кажучи, через місяць-другий роботи на TypeScript, коли тобі приходиться писати інтерфейси значно частіше, ніж класи, в тебе вже вимальовується чітке розуміння «що таке інтерфейс», чому в інтерфейсі не можна писати тіла методів, і чому в інтерфейсі використовуються виключно публічні модифікатори доступу.

я вот смотрю на ребят которые у меня в проекте уже около года педалят на тайпскрипте — и им это никак не помогло.

Ще одне доповнення до вищезазначеного мого опису відмінностей: інтерфейс — це «обрізана версія» абстрактного класу.

я не соглашусь с таким подходом )) хотя с точки зрения кода оно может и верно, но для меня это абсолютно разные вещи, хотя класс — любой, может выполнять роль и выполняет частную роль интерфейса

В абстрактному класі модифікатори доступу private й protected можуть використовуватись саме через те, що в ньому вже закладено базову частину функціональності, яку можна повторно використовувати в дочірніх класах.

Мда... не пам’ятаю що наштовхнуло мене на таку думку, але це твердження невірне. Обмеження по використанню модифікаторів доступу в інтерфейсі продиктоване архітектурним призначенням цього самого інтерфейсу.

Інтерфейс зобов’язаний гарантувати публічність доступу до будь-якого члену класу, що його імплементує. Це один з його головних «обов’язків». Абстрактний клас не завжди дає таку гарантію, хоча його теж можна використовувати в якості інтерфейса.

Ну прямо таки бином Ньютона. Интерфейс — определяет интерфейс, а абстрактный класс, соответственно, абстрактный класс.

Интерфейс можно рассматривать как абстрактный класс, все методы которого также абстрактны

как абстрактный класс, все методы которого
А конструктор/деструктор/прочие? #trollface

Не только лишь абстрактны, но еще и публичны.

Опытного человека вопросом в тупик не поставишь

Начиная с Java 8 этот вопрос действительно может напрячь

Не может, интерфейсов все также может быть несколько, а абстрактный класс один, в определении extends.

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

Я бы ответил следующее:
Абстрактный класс и интерфейс, являются способами/механизмами реализации в языке программирования такой концепции ООП как Абстракция. И ключевая разница между ними в том, что интерфейс дает — 100% абстракцию, в то время как абстрактный класс позволяет контролировать ее степень 0-100%
Ну а дальше, при желании, можно углубиться в конкретные отличия между данными сущностями (в зависимости от языка программирования).

Если правильно помню, то в контексте например, PHP в интерфейсе нет свойств и не определены методы. Всё перекладывается на наследников. А абстрактные классы уже могут реализовывать методы. От интерфейсов так же можно организовать множественное наследование.

На C++ интерфейсов вообще нет, там при множественном наследовании можно влипнуть в проблему ромба.

А на JS вообще остается только втыкать на prototype.

Может что-то напутал, потому что именно:

На работе занимаешься чем угодно, кроме сравнивания абстрактных классов с интерфейсами

Да и вообще стоит 2 раза подумать, стоит ли пытаться устраиваться на работу туда, где до сих пор на собеседованиях грузят подобными вопросами

На «плюсах» интерфейсы есть. Декларируются абстрактными классами, с лишь чиста-виртуальными функциями. :)

«Ромбы» разрешаются «виртуальными базовыми классами» — но до «ромбов» её нужно додизайнить.

Промахнулся веткой. Но тут ценный коммент ниже, не стоит удалять :D

Композишн везде модно, уже лет 10 как (если не больше). А наследование классов — для лузеров. :)

А на JS вообще остается только втыкать на prototype.
:D
Не зря я свчинулся с шарпа, хоть не буду такие вопросы на собеседованиях слышать)))

Но вообще в js новомодно сейчас не париться с наследованием, а делать composition через Object.assign()

Абстрактный класс може иметь/менять состояние, интерфейс нет.

Приветствую.

Если мы говорим о .NET / Java, то:

  1. Концептуально:
    • Интерфейс — описание котнракта взаимодействия c объектом, реализующим данный интерфейс
    • Абстрактный класс — непосредственно описание типа, которое влючает в себя не только контракт взаимодействия, а ещё и имплементацию некоторых методов. Но тем неменее не может быть инстаниирован. Так как описывает некий базовый контракт, для всех потомков данного абстрактного типа
    Я для себя принял такой подход: предметы реальности — это классы. Наборы их свойств и методов, которые можно логически объеденить в группы — интерфейсы.Опять же стоит создавать интерфейсы, только если тебе действительно надо обращаться к набору объектов разрозненных типов, по некому единому контракту. Т.е. создавать сущности по потребности, а не плодить тонны интерфесов, которые никогда не будут использованы и только усложнят процесс разработки
  2. Физически: ты не можешь унаследовать (покрайней мере в языках где нет множественного наследования) некий производный класс от нескольких других. Только один предок ! Однако, он может реализовывать несколько интерфейсов.
Пример:
Есть абстракнтный класс предметов физической реальности: часы, описывающий всевозможные предметы, которые показывают время (песочные, механические, электронные, атомные и т.д.) Значит делаем интерфейс IClock, описывающий как мы с этими часами можем взаимодействовать.
interface IClock
{
   DateTime CurrentTime {get; set;}
}
Интерфейс, можно и не делать, если мы не собираемся делать несколько сборок, которые будут делать свою ветку имплементации часов. Например у нас может быть под каждую платформу своя имплементация и в данном случае удобно выделить интерфейсы и выделить их в отдельную сборку, которую потом референсить в сборке с конкртеной имплементацией.

Далее,

abstract class Clock : IClock
{
  // Implement base clock logic. Base for all inheritors
}

Затем у нас есть конкретные часы, без будильника — механические.
Делаем:

class MechanicalClock : Clock
{
  // Extend / replace base clock logic with mechanical specific
}

Но у некоторых часов помимо самих часов, есть так же будильник, там смена мелодии и прочие штуки, соответственно делаем соответствующие интерфейсы: IAlarm, ...

Так же есть класс часов с будильником:

abstract class AlarmClock: Clock, IAlarm 
{
 // Alarm related logic
}

И электронных часоів с будильником:

class ElectronicClock : AlarmClock
{
  // 
}

Иногда, данный подход начинает порождать монстуозные иерархии, поэтому я придерживаюсь подхода, делать основую иерархию через наследование, а feature related через паттерн Strategy, т.е. сделать:

class AlarmStrategy: IAlarm
{
  // Implement all base alarm related logic
}
и
class ElectronicalClock : Clock, IAlarm
{
  private IAlarm alarmStrategy;
  public ElectronicalClock(IAlarm alarmStrategy)
  {
    this.alarmStrategy = alarmStrategy;
  }
  // Electronical clock related logic
}

Как то так

Да не согласен я! — Что, с Энгельсом или с Каутским? — С обоими! ©

А с чем согласен ? Интересно послушать...

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

Ок. А как бы ты сам изложил ?
P.S. Ну и как бы я не на интервью, попытался развёрнуто объяснить человеку что к чему, если что...

Да там человек как бы и так понимает , по крайней мере так он говорит в теме:)
А я тоже уже озвучивал.
По разному я описывал , когда меня этот вопрос спрашивали.
На последнем интервью , где меня его спросили я ответил так:
Абстрактный класс, отвечает на вопрос «кто я?»
Интерфейс на вопрос «что я делаю?»
Парнишка закивал и дополнительно по этому вопросу больше не спрашивал.
Оффер они мне так и не дали :)))

Да там человек как бы и так понимает , по крайней мере так он говорит в теме:)
Насколько я понял — он таки не знает, чем они отличаются, поэтому собственно и создал этот топик :) Или он чисто из любопытства ? :)
Абстрактный класс, отвечает на вопрос «кто я?»
Интерфейс на вопрос «что я делаю?»
Да, мне нравится, ёмкий ответ, при своей краткости. Спасибо.

Есть вопросы поинтересней. Типа в чем отличие статического класса от синглтона? :)

Это смотря для какого языка. В джаве например static class — немного о друшом, и много народу не знает.

Статический класс это класс иннициализирующийся сразу при запуске, а синглтон это паттерн позволяющий иметь не более одного обьекта?

Difference between Static class and Singleton Pattern:

— In c# a static class cannot implement an interface. When a single instance class needs to implement an interface for some business reason or IoC purposes, you can use the Singleton pattern without a static class.
— You can clone the object of Singleton but, you can not clone the static class object
— Singleton object stores in Heap but, static object stores in stack
— A singleton can be initialized lazily or asynchronously while a static class is generally initialized when it is first loaded

>в чем отличие статического класса от синглтона? :)

И то, и другое — плохо. Но синглтон хуже.

Спорно. Все зависит от задачи, к-я решается.

Нет таких задач/решений, где бы синглтон имел преимущество перед инстансом обычного (не синглтона) класса.

Если на данный момент у синглтона преимущество — это значит лишь то, что придётся намного больше времени и тpуда потратитъ на выковыривание синглтона из кода, позднее.

Если лепить синглтоны, не думая, то конечно потом будет потрачено время на выковыривание. Просто пример, IOC container, scope, unit tests. Или Вы предпочитаете руками писать синглтоны/не синглтоны, реализуя тем самым то, что уже придумано давно, т.е. велосипед(в народе)?

Никто не вынуждает делать IOC container синглтоном. И ни к чему хорошему, такое делание не приведёт.

Хорошо, тогда приведите аргументы против стнглтона. «Выковыривать из кода» не в счет.

Одна лишь его «глобальность» означает, что он собой загадит весь код.

Причём, в отличии от абстрактного класса — у него (как правило), ещё и есть состояние.

Хранить состояние можно, но осторожно, иначе возникает задача синхронизации.
Вы путаете муху и слона, сравнивая класс и инстанс класса. Граната в руках у обезьяны — очень серьёзное оружие.
Тема ушла в другое русло. Основное отличие — это возможность подменять реализацию, что в случае со статическим классом невозможно.

Вы путаете муху и слона, сравнивая класс и инстанс класса.

Это не путание. Как вы верно заметили, наличие состояния — добавляет ещё кучу головной боли (не только синхронизацию).

У абстрактного класса этой головной боли нет. Но у синглтона (вдобавок, к его глобальности) есть.

Потому и пишу:

И то, и другое — плохо. Но синглтон хуже.

Смешались в кучу кони, люди... При чем здесь абстрактный класс, если речь идёт о статическом классе?

о статическом классе

да, пардон... это я зарапортовался :)

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

Почти любой класс при работе в мультипоточной системе ничего не гарантирует.

Процитирую классиков

Don’t confuse the SINGLETON lifestyle (DI) with the Singleton design
pattern.

Use the SINGLETON lifestyle whenever it’s possible.

Красиво классик написал. А нет там нигде рядом описания как IOC container менеджит инстансы классов, к-е регистрируются с указанием scop-a жизни как singleton? Не задумывались?

Нет таких задач/решений, где бы синглтон имел преимущество перед инстансом обычного (не синглтона) класса.

Из последнего примера, для блжад скалы где фп и прочее: из спарк воркера надо дернуть БД.
Контекст выполнения на воркере тупая засеарилизированая лямбда, в которую ничего никак впринципе не заинджектить. Другое дело что в скалу синглтон в сам язык встроен.

Я всегда на этот вопрос отвечал, что абстрактный класс — это класс, в котором есть хотя-бы 1 абстрактный метод. А интерфейс, в отличии от класса, не предполагает реализации, а определяет поведение. Может это неправильное определение, но пока никто не поправил)

Забавно было когда меня на позицию C# trainee чувак с GL спросил: «а какой текст warning-a будет, если мы унаследуемся от абстрактного класса с виртуальным методом из dll-ки, не переопределив этот метод?». А перед этим он мне сказал: «если ты чето неправильно ответишь, то я тебя поправлять не буду, т.к. у меня нет на это времени. И вообще если в какой-то момент мне чето не понравится, собеседование закончится». Забавный чувак, я его запомнил =)

Может это неправильное определение, но пока никто не поправил)
Интерфейс это контракт

Абстрактный класс это контракт и/или реализация

Тут тоненько) Смотря как трактовать слово «предполагает». Если ближе к «(не)требует» — то да, можно придираться. Если ближе к «(не)возможно наличие» — то никакого несоответствия.

Я всегда на этот вопрос отвечал, что абстрактный класс — это класс, в котором есть хотя-бы 1 абстрактный метод. А интерфейс, в отличии от класса, не предполагает реализации, а определяет поведение. Может это неправильное определение, но пока никто не поправил)
не каждый абстрактный класс содержит абстрактные методы => твой ответ неверный

Я в курсе, хоть и давно не .Net-чик. Может быть и абстрактное свойство, или вообще их не быть. Но факт остается фактом, никто меня не исправлял и не просил уточнить как автора темы. Тем более если захотеть, можно прикопаться к любому определению.

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

Работать и проходить собеседования — два разных занятия, требующих 2х разных, обычно не пересекающихся, наборов скилов.

Внимание вопрос: «Зачем же ..ахать человеку мозг на собеседовании вопросами из множества, к-е не является подмножеством искомого множества»? ;)

1) Срезать зарплату
2) Пристыдить и косвенно заставить человека в своё свободное время повышать квалификацию в ускоренном темпе
3) Снизить требования к рабочему месту со стороны работника и число вопросов
4) Посмотреть на стрессоустойчивость, эго, агрессивность/защита/согласие, как вольётся в коллектив

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

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

1) Срезать зарплату
3) Снизить требования к рабочему месту со стороны работника
Так тупые вопросы обычно задают разработчики. Им же без разницы по сути какая у вас будет зарплата.

Это из-за узкой специализации/мышления. Потому они и разработчики, а не начальники. Начальнику или даже рядовому менеджеру важен продукт, практическое применение, а вот разработчик получает информацию ради самой информации, и не понимает что потом дальше с его кодом будет. Он думает что код это и есть продукт и его нужно улучшать. И ценность информации он определяет по сложности её изучения, а не по практической пользе для продукта. Лягушка в колодце.

Чето у вас все слишком сложно)

Тут ниже уже кто-то мыслю задвинул, что народ просто не знает че спрашивать и потому спрашивает фигню всякую, которую у них кто-то раньше спрашивал или что первое в голову взбрело. При том, что прохождение собеседований это реально meta-skill, но и проводить собеседования это такой-же meta-skill, который нужно тренировать. А народ иногда так боится, что даже сами не могут собеседовать, а берут коллегу в напарники, даже если этот коллега за 40 минут собеседования не проронит ни слова))

Вполне возможно. Мы объединили всех собеседователей в одно «нечто» — это какой-то самообман в попытке упростить для себя представление мира, снизив нагрузку для мышления. Это так же, как и делить людей на типы. В реальности же, два человека могут задать один и тот же вопрос, но из разных мотивов. Так что ответа на вопрос не существует т.к. сам вопрос не имеет никакого смысла.

Мы объединили всех собеседователей в одно «нечто»
Не совсем. Мы же тут про касту любителей тупых вопросов. По моему впечатлению, их не так много. В большем количестве мне попадались приятные люди. Редко они были просто запаренные и им было не до меня(особенно среди всяких CTO), а иногда бывали даже веселые. Неадекватов мне попадалось не так много, но они были яркие)
Им же без разницы по сути какая у вас будет зарплата.
Но их могут вы№%ть, если новый член комманды не будет соотвествовать ожиданиям. Потому для разработчиков, которые проводят собеседование, лучше отказать 100 подходящим кандидатам, чем взять одного неподходящего.

Вне контекста языка программирования этот вопрос просто бессмыслен.
В частности для С++ он бессмыслен.

Факінг шіт! Я завжди був впевнений що в плюсах є інтерфейси. :)

так вони є. просто не працюють. :)

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

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

Я ответил, что абстрактные классы использовал в основном в Java, а в Scala в основном Traits. Это не ответ, но возможное начало. Сейчас посмотрел — в двух проектах вообще нету абстрактных классов, в другом их в 10 раз меньше чем Traits. Я бы дальше мог подумать и назвать отличия, множественность и параметры точно. Но интервьюер сразу заявил, что они отличаются тем что в одних есть параметры, в других нету. Это ответ неполный и неточный — jiaminglin.gitbooks.io/…​t_and_abstract_class.html

Мне не понравилось, что он этим мог подразумевать, что я не могу ответить. Еще он сначала сказал, что не читал резюме, не взял список вопросов, но что-то поспрашивает, и что у него мало времени, потому что будет следующее собеседование по скайпу, постоянно доставал и смотрел время на телефоне и зачем-то принес вместе с моим резюме еще огромную пачку (других резюме?)

Я сказал, что параметры собираются добавить в виде docs.scala-lang.org/…​ing/trait-parameters.html, на замену текущих early definition (аналогичная фича, которая считается advanced ) чтобы намекнуть, что я вообще знаю и не только базовые вещи. На что он сказал, что мы говорим про то, что сейчас, а не то что будет и перешел к следующему вопросу. Дело не в том, что я не мог бы ответить вообще, а в том что интервьюер ждал сразу готового ответа, спешил и не слушал.

Но интервьюер сразу заявил, что они отличаются тем что в одних есть параметры, в других нету.
Я бы сам не ответил на этот вопрос, но про параметры — это ересь. Имхо (мой опыт из PHP), основная разница в назначении. Интерфейс это просто описание правил. Если класс имплементит интерфейс, то он точно будет иметь методы, описанные в интерфейсе. А абстрактный класс это заготовка, «полуфабрикат», где часть функций реализована, а часть должна быть реализована тем кто от него наследуется. И на практике можно не использовать ни то, ни другое. Зависит от проекта, фреймворка и программиста.

Когда вас спрашивают то сам ответ показывает уровень осознанности в использовании технологии.

Відповідь в SOLID, і не залежить від мови. Візьмемо для прикладу смартфон. Клас «Смартфон» імплементує інтерфейси (властивості смартфона) «дзвонити» і «фотографувати». Таким чином встановлюється протокол спілкування з іншими класами (фотограф або людина якій треба подзвонити). Фотографу потрібен фотоапарат, і йому не важливі інші функції, фотограф користується лише інтерфейсом «фотографувати». В той же час абстрактний клас це модель конкретного телефона — тобто сукупність всіх інтерфейсів, які імплементує клас, а також можливо реалізація якихось спільних функцій.

В go нет абстрактных классов, поэтому вопрос лишен смысла.

поэтому вопрос лишен смысла.
і як go
поэтому вопрос лишен смысла.
як і go
поэтому вопрос лишен смысла.
go і як

go як і

Ну хоть не люки в городе считать..

Это в каком яп? Если джава то ответ кагбы очевиден.

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

вообще про Scala и Traits, но ее мало кто знает, а вопрос явно передерт с джавовского, хотя ответ отличается.
у вас нету никаких навыков, которые вы автоматически делаете, но не можете сходу объяснить?

вообще про Scala и Traits, но ее мало кто знает
Та тут как раз народ в курсе)
Ток не очень понятно причем тут анонимные классы к скала.

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

В восьмой жабе тоже

Вот неплохой обзор stackoverflow.com/…​classes-instead-of-traits

Как видно, ничего неожиданного в ответах нет: параметры, наследование 1 класса против множества трейтов, интероперабельность с джавой.

В свежей скале 2.12.2 интероперабельность пошла дальше и трейт с реализацией компилится как Java интерфейс с реализацией

Самый топ когда тебя спрашивают: «Как вы себе представляете следующие 5 лет» на английском, а я даже на русском не знаю ответ на этот вопрос.

Дык, «i don’t know» — никто не отменял. :)

— fifty-fifty
— what do you mean?
— or sixty-thirty then

Самый топ когда на короткий вопрос ожидают длинный развёрнутый ответ.

Эти длинные монологи уместны где-нибудь на последнем звонке в школе, которую закончил много лет назад.

Может нужно ходить регулярно на собеседования для поддержания формы?

Конечно нужно. Для поддержания себя в форме, выработки скила проходить собеседования и понимания того, что вообще на рынке происходит.

Плюс как перестраховка, если резко уволят)

На последнем интервью, где меня спросили этот вопрос, ответил, что АК отвечаете вопрос «Кто я?», а И на вопрос «что я делаю?».
До сих пор думаю , почему меня не взяли , может им этот ответ не понравился.

скорее общее формулирование мыслей :D

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

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

Попробуйте применить абстрактный класс как маркер. Надеюсь вас это подтолкнет к ответу на вопрос ;)

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

Скорее несколько. Меня на собесах спрошали: чем руководствовались создатели языка, когда это писали. Хороший вопрос если есть возможность пораскинуть мозгами ;) теория теории теории — наше все.:)

чем руководствовались создатели языка, когда это писали

О! Это хорошие вопросы.

Всё просто. Интерфейс это хорошо, а абстрактный класс — плохо.

Хотя, если это абстрактный класс в C++ и только в дебаг версии — тоже может быть хорошо.
Или если это в Java/C# и класс (со всеми потомками) вписываются в «SRP» — тоже может быть неплохо.

Мне кажется, вы пропустили, чем вы замените использование абстрактного класса. Делегирование например. Вопрос, что лучше, в каких случаях, что применять и почему, как-то практичнее выглядит, чем «в чем разница».

А разве вопрос был , чем заменить?
Вопрос же был , в чем различие ?

тогда И — хорошо и АК — плохо, точно не ответ на этот вопрос. Или ответ, который еще расшифровать нужно.

Так то и с ответом что один хорошо , а второй плохо я тоже не согласный :) точнее попросил бы пояснения почему.

Самая простая замена — композиция. Можно также, попользовать статический полиморфизм.

Впрочем, как написал выше, если класс (с потомками) удовлетворяют «Single responsibility principle» — может прокатить и абстрактный класс (хоть это будет и хуже композиции, во многих смыслах).

Тогда был джуном
Сейчас
Вопрос ставит в ступор
Видимо джуном и остались ))

а по-моему дно пробито, если такие вопросы поднимаются на доу...

А меня ответы некоторых людей поражают :)
Сразу видно глубокое понимание основных концепций ООП.
Как по мне то «джуном» сразу можно ли аметист , по тому, что на такой вопрос они достают свой мешок с терминами котрый где то слышали и весь его высыпают в уши слушателей и там и интерфейсы маркеры и дженерики и полиморфизм, сука, не к ночи будет упомянут.

Можно пойти по нестандартному пути.
Например, вопрос «можно ли наследовать абстрактный класс от неабстрактного» многих вводит в ступор ))

Отличный вопрос, дабы послушать рассуждения будущего коллеги :)

Джуны как правило отвечают на этот вопрос без проблем
Если подобный вопрос задается на senior позицию, то это маркер, что в эту контору идти не нужно

Структура и класс. Есть типаж интервьюеров, который прется от подобных вопросов.

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

То есть вы допускаете, что я их неправильно применял? Подскажите как именно их можно неправильно использовать, может нужно исправляться? :)

Не использовать общие интерфейсы (кстати встречался с таким) вообще, не знать про всякие Sortable, Serizalizable etc? Писать abstract class вместо interface (не использовать абстрактных классов с параметрами конструктора, полями, реализованными и абстрактными методами) и не использовать более одного родительского типа? Пока все мимо.

Даже Вики вам скажет «Абстрактные классы представляют собой наиболее общие абстракции, то есть имеющие наибольший объём и наименьшее содержание.».
На практике часто туда попадает дублирующая функциональность, характерная для всех ваших реализаций интерфейса, тогда как сам такой класс не несёт в себе никакого практического смысла (может, кроме юнит-тестов в каких-то случаях).

Но не в Скала обычно. Абстрактные классы использовал в основном в Java, а в Scala в основном Traits. В двух проектах вообще нету абстрактных классов, в другом их в 10 раз меньше чем Traits. Traits как раз реализуют делегирование и сборку из кирпичиков.

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

Подписаться на комментарии