Подтвердить что ты не робот

Важность интерфейсов в Java

Скажем, у нас есть два класса: Tiger и Aeroplane. Одна вещь, общая для этих двух типов - скорость. Я знаю, что было бы нелогично создавать суперкласс ClassWithSpeed, а затем выводить из него подклассы Aeroplane и Tiger. Вместо этого лучше создать интерфейс, содержащий метод speed(), а затем реализовать его в Aeroplane и Tiger. Я понимаю. Но мы можем сделать то же самое без интерфейсов. Мы могли бы определить метод speed() в Aeroplane и метод speed() в Tiger. Единственным (возможно, очень большим) недостатком было бы то, что мы не смогли бы "достичь" объектов Tiger и Aeroplane через ссылку на интерфейс.

Я новичок в Java и OOP, и я был бы очень благодарен, если бы кто-то объяснил мне роль интерфейсов. Ура!

4b9b3361

Ответ 1

Это:

public int howFast(Airplane airplane) {
    return airplane.speed();
}

public int howFast(Tiger tiger) {
    return tiger.speed();
}

public int howFast(Rocket rocket) {
    return rocket.speed();
}

public int howFast(ThingThatHasntBeenInventedYet thingx) {
    // wait... what? HOW IS THIS POSSIBLE?!
    return thingx.speed();
}

...

против

public int howFast(Mover mover) {
    return mover.speed();
}

Теперь представьте, что вам нужно вернуться и изменить все эти функции howFast в будущем.

Интерфейс или нет, каждому классу придется реализовать или наследовать метод speed(). Интерфейс позволяет использовать эти разрозненные классы более легко, потому что каждый из них обещал вести себя определенным образом. Вы вызовете speed(), и они вернут int, поэтому вам не нужно писать отдельные методы для каждого возможного класса.

Когда вы обнаружите, что вам нужно обрабатывать скорость по-разному из-за прорыва в релятивистской физике, вам нужно только обновить методы, вызывающие speed(). Когда твоя правнучка пишет класс для HyperIntelligentMonkeyFish, ей не нужно разбирать свой древний бинарный файл и вносить изменения, чтобы ваш код мог контролировать и контролировать свою армию мутантов. Ей нужно только объявить, что HyperIntelligentMonkeyFish implements Mover.

Ответ 2

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

В динамическом языке (например, Python, Ruby и т.д.) вы можете просто вызвать метод скорости для любого произвольного объекта и обнаружить его во время выполнения, если он есть или нет.

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

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

С Java 8 разработчики языка пришли к выводу, что интерфейсы без какой-либо реализации были чрезмерно ограничительными (им не понравилось мое решение, я думаю;-)), поэтому они допускают реализацию по умолчанию, тем самым расширяя возможности интерфейсов с несколькими наследованиями, но при этом все еще пытаются избежать проблемы с конфликтующей реализацией через сложный набор правил приоритета, чтобы была реализована однозначная реализация по умолчанию.

Ответ 3

Я пытаюсь объяснить преимущества интерфейса в следующем примере -

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

someObject.someMethod(ClassWithSpeed)

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

someObject.someMethod(Tiger)
someObject.someMethod(AeroPlane)

Что теперь делать? Ваш вероятный ответ будет следующим: "I will use two overloaded method".

До сих пор это нормально, но

Скажем, вам нужно добавить дополнительные опции (скажем, автомобиль, цикл, кролик, черепаха... 100 других). Итак, что вы сделаете, чтобы изменить существующий код? вам нужно будет изменить много вещей.

Общий пример выше имеет только одну цель. То есть

"нам нужен интерфейс для создания лучшего, многоразового и правильно объектно-ориентированного дизайн"

N.B.

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

Ответ 4

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

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

  public double calculateSecondsToTravel( IObjectWithSpeed obj, double distance ) {
       return distance / obj.getSpeed();
  }

Интерфейсы позволяют нам удовлетворять принципу open/closed - открывать для расширения, но закрыты для модификации. Единственная реализация вышеописанного метода не нуждается в изменении, поскольку определены новые классы, которые реализуют IObjectWithSpeed.

Ответ 5

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

Так, например, если вам нужен класс Transport, который вычисляет эффективные маршруты, ему может быть присвоен класс, который реализует ClassWithSpeed в качестве параметра и использует свой метод speed() для вычисления того, что ему нужно. Таким образом, вы можете использовать его с нашим классом Aeroplane, но также и с любым классом, который мы определяем позже, например Boat. Java позаботится о том, чтобы, если вы хотите использовать класс в качестве параметра для Transport, он будет реализовывать ClassWithSpeed и что любой класс, реализующий ClassWithSpeed, реализует метод speed(), чтобы его можно было использовать.

Ответ 6

Я хочу найти много теоретических деталей, но попытаюсь объяснить этот пример.

Рассмотрим API JDBC. Это API, используемый для работы с параметрами, связанными с базой данных в Java. Сейчас в отрасли так много баз данных. Как написать драйверы для этого? Ну, быстрый и грязный подход может заключаться в написании собственной реализации с использованием наших собственных классов и API.

Но подумайте с точки зрения программиста. Будут ли они изучать DATABASE DRIVER API при использовании другой базы данных? Ответ НЕТ.

Итак, каково решение проблемы? Просто у вас есть четко определенный API, который любой может расширить для своей собственной реализации.

В JDBC API есть некоторые интерфейсы, которые являются Connection, ResultSet, PreparedStatement, Statement и т.д. Теперь каждый поставщик базы данных реализует интерфейс и напишет для него свою собственную реализацию. Результат?: Снижение усилий разработчика и простота понимания.

Теперь, из чего может состоять эта пользовательская реализация? Это просто. Они делают то, что, например, применяют интерфейс ResultSet и реализуют его, и в любом методе, возвращаемом ResultSet, возвращайте КЛАСС, ИСПОЛЬЗУЕМЫЙ Интерфейс ResultSet, подобный этому

ResultSet rs = новый ResultSetImpl();//это то, что они делают внутри.

Таким образом, интерфейс подобен контрактам. Они определяют, что ваш класс может сделать, и они дают гибкость вашего приложения. Вы можете правильно создавать свои собственные API-интерфейсы с помощью интерфейсов.

Надеюсь, это поможет вам.

Ответ 7

Интерфейс - это не просто подпись метода.

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

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

Ответ 8

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

Ответ 10

На уровне языка единственное использование интерфейсов, как вы уже упоминали, позволяет ссылаться на разные классы в общем виде. На уровне людей, однако, картина выглядит иначе: IMO Java сильная, когда используется в крупных проектах, где дизайн и реализация выполняются отдельными людьми, часто из отдельных компаний. Теперь вместо написания спецификации в документе Word системные архитекторы могут создавать кучу классов, которые разработчики могут затем непосредственно вставлять в свои IDE и начинать с них работать. Другими словами, удобнее вместо объявления, что "класс X реализует методы Y и Z, чтобы использовать их для цели A, просто чтобы сказать, что" класс X реализует интерфейс A "

Ответ 11

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

Class Tiger {
  public MovingEntity mover;

 public Tiger(){

  mover.speed=30;
  mover.directionX=-1;
  mover.move(mover);

 }

}
Class Plane {
  public MovingEntity mover;

 public Plane(){
  mover.speed=500;
  mover.directionX=-1;
  mover.move(mover);

 }


Abstract Class Moverable(){
  private int xPos;
  private int yPos;
  private int directionX;
  private int directionY;
  private int speed;


Class MovingEntity extends Moverable {
 public void move(Moverable m){
   if(m instanceof Tiger){

      xPos+=directionX*speed;
      yPos+=directionY*speed;

   }else if(m instanceof Plane){
      xPos+=directionX*speed;
      yPos+=directionY*speed;

   }
 }

Ответ 12

Поскольку созданный интерфейс дает вам Polymorphism, на всех этих классах, то есть на Tiger и Airplane.

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

Вы используете интерфейсы, если хотите добавить дополненную функциональность для своего класса в дополнение к своей основной функциональности. Таким образом, использование интерфейсов даст вам Полиморфизм, даже если это не функциональность вашего класса (потому что вы ввели контракт, реализовав интерфейс). Это огромное преимущество перед созданием метода speed() для каждого класса.