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

Не волнуйся, я знаю, о чем ты думаешь. Что такое интерфейс?

Интерфейс - это контракт. В контракте вы детализируете поведение этого интерфейса в виде различных методов, которые он использует. Затем любые классы, которые должны разделять поведение этого интерфейса, должны реализовать этот интерфейс. По сути, когда класс реализует интерфейс, он «подписывает» контракт интерфейса, который подтверждает, что класс предоставит все методы из интерфейса.

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

public interface Car {
    public String startTheEngine();
}

Это важное поведение, которое нам нужно знать автомобилю, но в реальном мире существует не только один тип автомобиля. У нас есть множество различных брендов Toyota, Nissan, BMW и т. Д. В нашей программе каждый из этих брендов будет представлен отдельным классом, и, хотя бренды разные, им все равно потребуется основное поведение из нашего интерфейса Car. Следовательно, все классы будут реализовывать Car.

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

public class BMW implements Car {
  public String startTheEngine() {
      return pushRedButton();
  }
public class Nissan implements Car {
  public String startTheEngine() {
      return pushBlueButton();
  }

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

Существует ли Ruby-эквивалент интерфейса Java? Строго говоря, не совсем.

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

У вас может быть класс Game с методом get_next_move, который получает ход от HumanPlayer и ComputerPlayer. Для этого используется player_type, переданный методу get_next_move, чтобы гарантировать, что правильный класс вызывается для соответствующего хода каждого игрока.

def get_next_move(player_type) 
  player_move = player_type.make_move
  mark_move_on_board(player_move)
end

То, как на самом деле делается ход, зависит от типа игрока. Хотя каждый объект проигрывателя имеет один и тот же метод make_move, код внутри метода каждого проигрывателя может быть разным. Единственное требование (которое контролирует невидимый интерфейс) состоит в том, чтобы значение, возвращаемое каждым методом, было строкой, поскольку это тип данных, необходимый для метода mark_move_on_board (player_move).

В Ruby для создания того же поведения, что и интерфейса в Java, задействованы два элемента; идея невидимого «интерфейса», в котором каждый класс Human и Computer имеет метод get_next_move и возвращает строку и полиморфизм.

** Компромиссы **

  • Я хорошо знаю программу, поэтому я знаю типы данных необходимых аргументов, но кто-то, читающий мой код Ruby, может не знать. Это одно из огромных преимуществ Java, его типы данных явно указаны, поэтому легко увидеть, какой метод вернет. Точно так же интерфейс похож на категорию, в которую входят классы, что упрощает понимание общего намерения классов и того, как они должны себя вести.
  • Руби очень добрая. Он выполняет большую работу за кулисами, но, возможно, он помогает пройти через шаги и выполнить работу, на которой настаивает Java, возможно, это сделает ваш код более понятным.