Пришел, увидел, обобщил: погружаемся в java generics

Статические методы (static методы)

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

Пример:

Monstr.java

Java

public interface Monstr {
boolean isSensitiveToSilver();
void logic(VisibleWorld visibleWorld);

static void logicForSensitiveToSilver(Monstr[] monstrs,
VisibleWorld visibleWorld) {
for (Monstr monstr : monstrs) {
if (monstr.isSensitiveToSilver()) {
monstr.logic(visibleWorld);
}
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13

publicinterfaceMonstr{

booleanisSensitiveToSilver();

voidlogic(VisibleWorld visibleWorld);

staticvoidlogicForSensitiveToSilver(Monstrmonstrs,

VisibleWorld visibleWorld){

for(Monstr monstrmonstrs){

if(monstr.isSensitiveToSilver()){

monstr.logic(visibleWorld);

}

}

}

}

Цикл статей «Учебник Java 8».

Следующая статья — «Java 8 наследование».
Предыдущая статья — «Java 8 вложенные классы и лямбда-выражения».

Что такое интерфейс?

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

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

Рассмотрим следующую картинку. У нас есть контракт (интерфейс), в котором описано какие действия должна выполнять мышка. Это например, клик по правой клавише и клик по левой. Разные производители мышки (классы), реализующие данный контракт (интерфейс), обязаны спроектировать мышки, у которых будут эти действия. Но как выглядят мышки, какие дополнительные опции будут иметь — все это решает сам производитель. 

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

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

Все методы интерфейса являются и эти модификаторы тоже необязательны. Объявляемые методы не содержат тел, их объявления завершаются точкой с запятой:

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

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

Класс Robot из вышеуказанной схемы:

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

Например, класс реализует только один метод интерфейса , поэтому он абстрактный:

Тип интерфейса можно указывать при объявлении переменных, содержащих ссылки на объекты, классы которых реализуют этот интерфейс. Например, в следующем примере переменная имеет тип , и указывает она на объект . Но на основе интерфейсов нельзя порождать объекты. Например, в строке будет ошибка компиляции. При использовании переменной типа интерфейс, доступны только те члены класса, которые определены в этом интерфейсе. Например, нельзя вызвать метод , используя переменную . А для переменной можно:

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

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

PHP XML

Background of Generics

Generics were introduced in JDK 5 to eliminate compile-time errors and strengthen type safety. This extra type-safety eliminates casting in some use cases and empowers programmers to write generic algorithms, both of which can lead to more readable code.

For example, pre-JDK 5, we’d have to work with the elements of a list using casting. This, in turn, created a certain class of runtime errors:

Now, this code has two issues we’d like to address:

  • We need an explicit cast to extract values from aList – the type depends on the variable type on the left – Integer in this case
  • We’ll get a runtime error on the second iteration when we’re trying to cast a_string to an Integer

Generics fill the role for us:

The compiler will tell us that it’s not possible to add a_string to a List of type Integer, which is better than finding out at runtime.

Moreover, no explicit casting is needed since the compiler already knows that iList holds Integers. Additionally, due to the magic of unboxing, we didn’t even need an Integer type, its primitive form is enough.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector