Я попытаюсь ответить, используя практический сценарий, чтобы показать различие между ними.
Интерфейсы имеют нулевую полезную нагрузку, т. е. никакое состояние не должно поддерживаться и, следовательно, лучше выбирать только ассоциировать контракт (возможность ) с классом.
Например, скажем, у меня есть класс Task, который выполняет какое-то действие, теперь для выполнения задачи в отдельном потоке мне действительно не нужно расширять класс Thread, а лучше выбирать Задача реализует интерфейс Runnable (т. Е. Реализует его метод run ()), а затем передает объект этого класса Task в экземпляр Thread и вызывает его метод start ().
Теперь вы можете спросить, что, если Runnable был абстрактным классом?
blockquote>Ну, технически это было возможно, но дизайн был мудрым, что было бы плохой причиной выбора:
- Runnable не имеет состояния, связанного с он и ни один из них не предлагает никакой реализации по умолчанию для метода run ()
- Задача должна была расширять ее, поэтому она не могла бы расширять любые другие c lass
- Задача не может быть предложена как специализация класса Runnable, все, что ей нужно, это переопределить метод run ()
. Другими словами, классу Task необходимо было быть запущен в потоке, который он достиг, реализуя стили интерфейса Runnable, расширяющие класс Thread, которые сделают его потоком.
Просто добавьте нам интерфейс для определения возможности (контракта), а используйте абстрактный класс для определения скелета (общей / частичной) реализации.
blockquote>Отказ от ответственности: глупый пример следует, постарайтесь не судить :-P
interface Forgiver { void forgive(); } abstract class GodLike implements Forgiver { abstract void forget(); final void forgive() { forget(); } }
Теперь у вас есть был выбран выбор, чтобы быть GodLike, но вы можете выбрать только Forgiver (т.е. а не GodLike) и do:
class HumanLike implements Forgiver { void forgive() { // forgive but remember } }
Или вы можете выбрать, чтобы быть GodLike и делать:
class AngelLike extends GodLike { void forget() { // forget to forgive } }
P.S. с интерфейсом java 8 также могут иметь статические, а также методы по умолчанию (переопределяемые реализации), и, таким образом, интерфейс b / w с разницей и абстрактный класс еще более сужаются.
Согласно этому выпуску GitHub , он находится в отставании, которое будет реализовано в следующей версии EF Core. И из этого GitHub Issue , вот объяснение, которое вы искали:
Причина в том, что он использовал комбинацию Key и Column для упорядочения, но упорядочение столбцов не то же самое, что порядок ключей, и это вызвало путаницу и проблемы в EF6. Изменение существующих аннотаций данных также является дорогостоящим из-за их связи с .NET Core и .NET Framework.
Тем не менее, мы видим ценность в возможности использовать эту и другие общие конфигурации с использованием атрибутов, поскольку переход к свободному API может быть большим. Поэтому мы рассмотрим создание новой библиотеки / пакета с дополнительными новыми атрибутами конфигурации EF, которые можно использовать вместе с аннотациями данных. Это будет одна из вещей, которая будет реализована там.
blockquote>Однако, Согласно этому объявлению , из ASP.NET Core 3.0 вы можете использовать все функции EF 6.x с ASP.NET Core, так как будет EF 6.3 в .NET Core> = 3,0