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();
}