Класс против интерфейса - PullRequest
2 голосов
/ 27 августа 2009

Недавно в одном из интервью меня спросили, можно ли рассматривать интерфейс как класс в C #? То есть такое интерфейс это класс в C #?

Я был смущен.

Какой может быть ответ?

Ответы [ 7 ]

8 голосов
/ 27 августа 2009

Нет, интерфейс не является классом.

Интерфейс - это набор сигнатур методов и, возможно, свойств, которые связаны с одной идеей. Например, интерфейс IList будет иметь методы для индексации, вставки и получения количества элементов. Тем не менее, он не определяет детали реализации. Интерфейс списка может быть реализован в виде связанного списка, или обернутого массива, или чего угодно, если только он определяет эти методы в интерфейсе.

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

Так что нет, интерфейс не является классом, так как он просто определяет конкретный контракт, а класс определяет все поведение объекта.

Commenter SquareCog точно указывает, что вышесказанное не совсем верно. Поскольку классы могут быть разделены на подклассы, а методы переопределены, отношение класса к реальному поведению объекта становится несколько более сложным. Я просто собираюсь решить эту проблему, сказав, что классы - это отдельные сущности. Вы можете прочитать исходный код класса и узнать, какое поведение этот класс охватывает. Однако во время выполнения объекты имеют типы вместо классов. Типы - это целое дерево наследования вместо единственного класса, и, таким образом, поведение типа может быть определено для нескольких различных классов. К счастью, это не меняет принципиальной концептуальной разницы, заключающейся в том, что интерфейсами являются контракты, которые могут подразумевать (через имена, типы аргументов и т. Д.) Определенные реализации, но не могут применять что-либо, кроме сигнатур методов, в то время как классы определяют реализацию, даже если это не так. фактическая реализация, используемая во время выполнения.

3 голосов
/ 27 августа 2009

С логической точки зрения они очень похожи. Как отмечали другие, ABC 1 с только публичными абстрактными членами будет служить почти той же цели, что и интерфейс.

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

  • Класс может только наследовать от одного базового класса, но может реализовать множество интерфейсов.
  • Тип значения, уже производный от ValueType, не может наследоваться от ABC, но может реализовывать интерфейс.
  • Класс может содержать поля и статические члены. Интерфейс не может.
  • Класс может содержать реализацию, интерфейс не может.
  • Класс может иметь закрытые и защищенные члены, интерфейс не может.
  • Абстрактные члены азбуки всегда виртуальны. Класс может реализовывать интерфейс с не виртуальными членами.

1: Абстрактный базовый класс

2 голосов
/ 27 августа 2009

Интерфейс Java не является классом; это объявление методов, которые должны быть реализованы классами; описание способностей, если хотите. Абстрактные классы в Java являются интересным промежуточным пунктом между собственными классами и интерфейсами, поскольку они определяют доступные методы, но также предоставляют некоторые реализации по умолчанию.

Принципиальное различие между абстрактным классом и интерфейсом в Java заключается в том, что вы можете расширить только один класс; Вы можете реализовать несколько интерфейсов. Абстрактный класс описывает, кем вы являетесь; интерфейс описывает, что вы можете сделать . То, чем вы являетесь, также определяет, что вы можете сделать, но оно имеет значительно более сильный смысл.

2 голосов
/ 27 августа 2009

Да, любой абстрактный класс, который не содержит реализации и состоит только из абстрактных методов, будет эквивалентен интерфейсу.

1 голос
/ 27 августа 2009

В общем, Интерфейс - это тип, который может быть реализован классом, чтобы указать, что класс представляет поведение через набор методов. Например, .Net имеет интерфейс ICollection, который содержит методы для взаимодействия с коллекцией.


В C ++ интерфейс - это класс, в котором каждый метод является абстрактным.

В Java и .Net интерфейсы являются независимыми типами, не связанными с классами.

В любом случае классы могут реализовывать интерфейсы.

1 голос
/ 27 августа 2009

Может быть несколько ответов.

Нет, класс не является интерфейсом - интерфейс определяет контракт, класс - это тип объекта, который может быть создан.

Да, интерфейс можно рассматривать как базовый класс только с виртуальными методами - так определяются интерфейсы в C ++.

0 голосов
/ 09 июля 2012

Полезно рассматривать .net как имеющий три «безопасных» типа типов в .net: интерфейсы, классы и типы значений (есть также такие вещи, как указатели и тому подобное, но это другая история) и три основных Могут использоваться классы контекстов: места хранения, объекты кучи и общие ограничения.

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

Места хранения также могут быть любого типа, но места хранения ценностного типа отличаются от других. Место хранения типа класса или типа интерфейса содержит ссылку на класс. Место хранения типа значения содержит либо примитив значения (байт, целое число, символ, число с плавающей точкой и т. Д.), Либо содержит место хранения для каждого поля типа значения (например, место хранения типа *). 1005 * содержит два хранилища типа Int32, каждое из которых содержит подписанный 32-битный целочисленный примитив).

Общие ограничения также могут быть любого типа, но ограничения типов интерфейса не ограничивают сам параметр ограниченного универсального типа как тип класса, тип интерфейса или тип значения. Метод, объявленный void Foo<T>(T param) where T:IWowzo, может быть вызван с параметром типа класса, типа интерфейса или типа значения. Если подпрограмма вызывается с параметром типа значения, то param и любые другие места хранения, объявленные как тип T, будут сохранены как типы значений. Если подпрограмма вызывается с параметром типа класса или целочисленного типа, то param и любые другие места хранения, объявленные как тип T, будут сохранены как ссылки на классы. Важно отметить, что если T сам по себе является типом интерфейса (IWozo или производным), то param будет передан как ссылка на объект кучи и будет вести себя как единое целое независимо от того, является ли тип объекта Экземпляр - это объект класса или тип значения. Если struct Bar реализует IWowzo, а myBar - это переменная типа Bar, вызов Foo<Bar>(myBar) может дать семантику, отличную от Foo<IWowzo>(myBar); в первом случае параметр будет вести себя как тип значения, а во втором - как тип класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...