Рубрики
Без рубрики

Создайте свободный Интерфейс на Java менее чем за 5 Минут

(Переходим к хорошей части!) Построение базового класса Построение классов внутри… С пометкой java, новички, учебник, ооп.

(Переходим к хорошей части!)

Построение базового класса

Создавать классы на Java ЛЕГКО! Все, что вам нужно, это объявление класса внутри файла с тем же именем, что и у класса (но с .java в конце). Минимальным примером может быть что-то вроде

// MyClassName.java

// class must be public and created in a file called .java
public class MyClassName {
  // no other code needed!
}

Вы можете поместить приведенный выше код в файл с именем MyClassName.java и загрузите его в оболочку с /открытым команда:

jshell> /open MyClassName.java

jshell> MyClassName j = new MyClassName()
j ==> MyClassName@6c3708b3

…вот и все! Потому что Имя моего класса (как и все классы) расширяет Объект , мы получим некоторые встроенные методы, если наберем j. в оболочке и нажмите клавишу вкладка :

jshell> j.
equals(       getClass()    hashCode()    notify()      notifyAll()   toString()    wait(         

Создание пользовательского конструктора

Конечно, это не очень увлекательно. Часто мы создаем наши собственные конструкторы , чтобы придать объектам определенное состояние (переменные экземпляра и т. Д.). Давайте добавим несколько частных переменных, которые мы можем задать с помощью конструктора:

// MyClassName2.java

// class must be public and created in a file called .java
public class MyClassName2 {

  private int instanceInt;
  private double instanceDouble;
  private String instanceString;

  public MyClassName2 (int myInt, double myDouble, String myString) {
    this.instanceInt = myInt;
    this.instanceDouble = myDouble;
    this.instanceString = myString;
  }
}

Теперь, если мы попытаемся создать экземпляр MyClassName2 в оболочке с использованием конструктора без аргументов по умолчанию, мы получим ошибку:

jshell> /open MyClassName2.java

jshell> MyClassName2 j2 = new MyClassName2()
|  Error:
|  constructor MyClassName2 in class MyClassName2 cannot be applied to given types;
|    required: int,double,java.lang.String
|    found: no arguments
|    reason: actual and formal argument lists differ in length
|  MyClassName2 j2 = new MyClassName2();
|                    ^----------------^

…это связано с тем, что конструктор с нулевым аргументом по умолчанию предоставляется Java только , если другие конструкторы не определены. Поскольку мы определили наш конструктор с тремя аргументами ( int , double , String ) выше, это единственный, к которому у нас есть доступ на данный момент. Итак, давайте создадим объект MyClassName2 :

jshell> MyClassName2 j2 = new MyClassName2(42, 3.14, "bonjour le monde!")
j2 ==> MyClassName2@6c3708b3

…отлично! Это сработало!

Добытчики и сеттеры

Добытчики

Однако, чтобы получить что-либо из этого объекта, нам понадобятся некоторые добытчики . Давайте добавим эти:

// MyClassName3.java

// class must be public and created in a file called .java
public class MyClassName3 {

  private int instanceInt;
  private double instanceDouble;
  private String instanceString;

  public MyClassName3 (int myInt, double myDouble, String myString) {
    this.instanceInt = myInt;
    this.instanceDouble = myDouble;
    this.instanceString = myString;
  }

  // getters are methods, so they have a return type
  public int getMyInt() {
    return this.instanceInt;
  }

  // we use 'this' to refer to the object calling the method
  public double getMyDouble() {
    return this.instanceDouble;
  }

  // ('this' isn't strictly necessary here, but it can make the code clearer)
  public String getMyString() {
    return this.instanceString;
  }

}

Теперь мы можем создать объект с некоторыми параметрами и извлечь эти параметры позже!

jshell> /open MyClassName3.java

jshell> MyClassName3 j3 = new MyClassName3(17, 1.618, "hola mundo!")
j3 ==> MyClassName3@335eadca

jshell> j3.getMyInt()
$5 ==> 17

jshell> j3.getMyDouble()
$6 ==> 1.618

jshell> j3.getMyString()
$7 ==> "hola mundo!"

Сеттеры

Установщики позволяют нам изменять состояние объекта. Другими словами, они позволяют нам изменять значения, хранящиеся в переменных экземпляра объекта. Сеттеры – это просто методы, которые принимают параметр и устанавливают переменную экземпляра, равную этому параметру. Давайте добавим немного:

// class must be public and created in a file called .java
public class MyClassName4 {

  private int instanceInt;
  private double instanceDouble;
  private String instanceString;

  public MyClassName4 (int myInt, double myDouble, String myString) {
    this.instanceInt = myInt;
    this.instanceDouble = myDouble;
    this.instanceString = myString;
  }

  // getters are methods, so they have a return type
  public int getMyInt() {
    return this.instanceInt;
  }

  // we use 'this' to refer to the object calling the method
  public double getMyDouble() {
    return this.instanceDouble;
  }

  // ('this' isn't strictly necessary here, but it can make the code clearer)
  public String getMyString() {
    return this.instanceString;
  }

  public void setMyInt (int newInt) {
    this.instanceInt = newInt;
  }

  public boolean setMyDouble (double newDouble) {
    this.instanceDouble = newDouble;
    return true;
  }

  public String setMyString (String newString) {
    this.instanceString = newString;
    return this.instanceString;
  }

}

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

Но философия возвращаемых значений от сеттеров делится на несколько лагерей:

  • Если ваш сеттер всегда, в обязательном порядке успешно установит значение, некоторые люди вернут void из метода сеттера.
  • Если есть вероятность, что ваш сеттер может выйти из строя, вы также можете вернуть логическое значение с true указывает, что переменной экземпляра было успешно присвоено указанное значение
  • Или вы можете просто вернуть переменную экземпляра, о которой идет речь, в конце метода. Если он был успешно изменен, возвращаемое значение будет отражать это.

Эти три философии были применены по порядку к сеттерам, приведенным выше. Давайте посмотрим на них в действии:

jshell> MyClassName4 j4 = new MyClassName4(19, 2.71828, "hello world!")
j4 ==> MyClassName4@72b6cbcc

jshell> j4.getMyInt(); j4.setMyInt(23); j4.getMyInt()
$10 ==> 19
$12 ==> 23

jshell> j4.getMyDouble(); j4.setMyDouble(1.2345); j4.getMyDouble()
$13 ==> 2.71828
$14 ==> true
$15 ==> 1.2345

jshell> j4.getMyString(); j4.setMyString("aloha honua"); j4.getMyString()
$16 ==> "hello world!"
$17 ==> "aloha honua"
$18 ==> "aloha honua"

Мы можем видеть (на несуществующем шаге $11 ) это set myInt() возвращает пустоту. В оболочке значение не отображается .

установите мой Double() возвращает истину , хотя значение было успешно изменено. Мы можем видеть это на этапах “до” ( 13 долларов США ) и “после” ( 15 долларов США ).

Наконец, set myString() возвращает значение этой строки.экземпляр в конце метода. Поскольку переменная экземпляра была успешно изменена, возвращаемое значение отражает это.

Плавные интерфейсы

Но мы можем вернуть любое значение, которое мы хотим от метода! Нет причин, по которым мы не могли бы вернуться -14 или "r2349jp3giohtnr" или ноль от любого из этих поселенцев. Нет никаких ограничений на то, какую ценность мы можем вернуть.

Так что же произойдет, если мы вернемся этот ?

Давайте попробуем это сделать! Давайте изменим наш метод setMyInt() на возврат this , который является ссылкой на объект, вызывающий метод (в данном случае метод setMyInt() ):

  public MyClassName5 setMyInt (int newInt) {
    this.instanceInt = newInt;
    return this;
  }

Я удалил остальную часть класса для краткости, но он должен быть таким же, как MyClassName44 изменен на 5 повсюду). Так как же работает этот метод? Ну, он возвращает объект, который вызвал метод, который в данном случае является объектом MyClassName5 , поэтому нам нужно сделать это возвращаемым значением. Давайте попробуем этот метод и посмотрим, что получится:

jshell> MyClassName5 j5 = new MyClassName5(0, 0.0, "zero")
j5 ==> MyClassName5@5d76b067

jshell> j5.setMyInt(-1)
$21 ==> MyClassName5@5d76b067

Посмотрите на возвращаемые значения из этих двух операторов в оболочке – они одинаковые! Они оба возвращают объект MyClassName5@5d76b067 . Если это правда, разве мы не должны иметь возможность вызывать другой метод для значения, возвращаемого из setMyInt() ? Давайте попробуем это сделать!

jshell> j5.getMyInt()
$22 ==> -1

jshell> j5.setMyInt(2).setMyDouble(2.2)
$23 ==> true

jshell> j5.getMyInt(); j5.getMyDouble()
$24 ==> 2
$25 ==> 2.2

Посмотрите, что там произошло! Цепочка методов сработала! Но возвращаемое значение (в 23 доллара ) было истинным , потому что semidouble() по-прежнему возвращает логическое значение . Если мы изменим все наши сеттеры, чтобы вернуть объект MyClassName 5 , мы сможем связать их вместе в любом порядке!

Давайте создадим MyClassName6 с сеттерами, которые возвращают объекты MyClassName6 , аналогично тому, что мы сделали выше. Опять же, я напишу здесь только сеттеры, чтобы сэкономить место:

  public MyClassName6 setMyInt (int newInt) {
    this.instanceInt = newInt;
    return this;
  }

  public MyClassName6 setMyDouble (double newDouble) {
    this.instanceDouble = newDouble;
    return this;
  }

  public MyClassName6 setMyString (String newString) {
    this.instanceString = newString;
    return this;
  }

Давайте попробуем это сделать!

jshell> MyClassName6 j6 = new MyClassName6(6, 6.6, "six")
j6 ==> MyClassName6@131276c2

jshell> j6.setMyString("seven").setMyDouble(77.77).setMyInt(777)
$28 ==> MyClassName6@131276c2

jshell> j6.getMyString(); j6.getMyDouble(); j6.getMyInt()
$29 ==> "seven"
$30 ==> 77.77
$31 ==> 777

Вот и все! Все, что нам нужно было сделать, чтобы связать методы вместе, – это вернуть this . Возврат этого позволяет нам последовательно вызывать метод за методом, и все эти методы будут применены к одному и тому же (исходному) объекту!

Идея, которая очень похожа на интерфейсы fluent, – это шаблон Builder , который работает почти так же, как описанные выше сеттеры, но это тема для другой статьи.

Обязательно дайте мне знать в комментариях, если у вас есть какие-либо вопросы или критические замечания!

Оригинал: “https://dev.to/awwsmm/build-a-fluent-interface-in-java-in-less-than-5-minutes-m7e”