OOP - точка интерфейса

Возможный дубликат:
Интерфейс против абстрактного класса (общий OO)

EDIT: Я просто прочитал вопросы и ответы на вопросы из "возможного дубликата", и мне очень грустно, что кто-то считает эти два вопроса даже похожими... но, о хорошо...

-------------------------------------------- -----------------------------

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

Что я не понимаю, нам нужно проверить, реализует ли класс интерфейс с instanceOf каждый раз, когда мы вызываем его методы? Без чтения документации вы понятия не имеете, какой класс реализует интерфейс. И если вы читаете код, чем видите, что этот метод определен, и вы можете его назвать?!

Если у меня

случай А.

class Ball{
function kick(){...};
}

или случай В.

interface Kickable{
function kick;
}

class Ball implements Kickable{
function kick(){...};
}

Единственное различие заключается в том, что в случае A я получаю сообщение об ошибке при вызове метода, которого он не существует ( "во время выполнения" ), и в случае B я получу эту ошибку при попытке запустить код while пытаясь "скомпилировать". Runtime и компиляция определенно используются неправильно здесь (среда PHP).

Я помню, в Java появился интерфейс Runnable, который позволяет выполнять потоки. Почему мы должны реализовать интерфейс Runnable, а затем определить метод run() в этом классе? Я имею в виду, что класс может иметь метод Run без реализации интерфейса, и есть средства для проверки того, имеет ли класс специальный метод. Хорошо, может быть, моя часть Java вопроса немного запутанна:)))

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

Спасибо, Luka

Ответ 1

Вы уже назвали большинство преимуществ интерфейсов в своем вопросе, а именно:

  • они допускают множественное (интерфейсное) наследование

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

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

Это в основном ре-хэш первого пункта выше, но он ставит его в перспективе, которую вы, возможно, раньше не рассматривали. Возьмите пример Java Runnable: если Runnable был абстрактным классом, то любой и каждый класс, который реализует потоки, должны были бы наследовать от него. В конечном итоге это приведет к чрезвычайно негибкому коду, поскольку вы не сможете наследовать ни один другой базовый класс. Однако, поскольку Runnable - это интерфейс, вы можете реализовать любой класс (независимо от того, какой базовый класс он может наследовать).

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

На строго типизированном языке, таком как Java, у вас, как правило, нет таких проблем, поскольку вы получите ошибку времени компиляции, если вы вызываете метод интерфейса для класса, который не реализует интерфейс (или doesn ' t реализует конкретный метод).

Ответ 2

Нет. Вы не должны использовать instanceof. Это для проверки типа времени выполнения. Если вы хотите убедиться, что используете класс, который реализует этот интерфейс, просто введите тип интерфейса в свою подпись метода. Например

public interface yourInterface{
      public void foo();
}

public class yourClass implements yourInterface{
     public void foo(){} //you need to implement this method, otherwise it won't compile
}

public class anotherClass{
     public void bar(yourInterface object){} //you can pass any object to "bar" method if the object implements yourInterface. yourClass object will be fine
}

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

class generiClass<T extends yourInterface>{
      public void genericMethod(T object){} //you can use a generic T class, but T needs to implement yourInterface
}

Причиной интерфейсов является в основном 2:

  • заставить класс реализовать некоторые методы.
  • Разрешить множественное наследование, например, функции на языке без множественного наследования (на языке, таком как С++, где у вас есть множественное наследование, вам не нужен интерфейс. Или, говоря об этом лучше, интерфейсы - это то же самое, что и чистый абстрактный класс)

Ответ 3

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

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

Пример:

function foo($obj) {
  $obj->bar(); // fails with foo(array());
}

против

interface foobar {
  function bar();
}

function foo(foobar $obj) { // $obj *must* have a bar() method
  $obj->bar();
}