Android interface static method

Static method in Interface in Java

Static Methods in Interface are those methods, which are defined in the interface with the keyword static. Unlike other methods in Interface, these static methods contain the complete definition of the function and since the definition is complete and the method is static, therefore these methods cannot be overridden or changed in the implementation class.
Similar to Default Method in Interface, the static method in an interface can be defined in the interface, but cannot be overridden in Implementation Classes. To use a static method, Interface name should be instantiated with it, as it is a part of the Interface only.
Below programs illustrate static methods in interfaces:
Program 1: To demonstrate use of Static method in Interface.
In this program, a simple static method is defined and declared in an interface which is being called in the main() method of the Implementation Class InterfaceDemo. Unlike the default method, the static method defines in Interface hello(), cannot be overridden in implementing the class.

Attention reader! Don’t stop learning now. Get hold of all the important Java Foundation and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more, please refer Complete Interview Preparation Course.

Источник

Java 8 for Android Development: Default and Static Methods

Java 8 was a huge step forward for the programming language and now, with the release of Android Studio 3.0, Android developers finally have access to built-in support for some of Java 8’s most important features.

In this three-part series, we’ve been exploring the Java 8 features you can start using in your Android projects today. In Cleaner Code With Lambda Expressions, we set up our development to use the Java 8 support provided by Android’s default toolchain, before taking an in-depth look at lambda expressions.

In this post, we’ll look at two different ways that you can declare non-abstract methods in your interfaces (something that wasn’t possible in earlier versions of Java). We’ll also answer the question of, now that interfaces can implement methods, what exactly is the difference between abstract classes and interfaces?

We’ll also be covering a Java 8 feature that gives you the freedom to use the same annotation as many times as you want in the same location, while remaining backwards compatible with earlier versions of Android.

But first, let’s take a look at a Java 8 feature that’s designed to be used in combination with the lambda expressions we saw in the previous post.

Write Cleaner Lambda Expressions, With Method References

In the last post, you saw how you can use lambda expressions to remove lots of boilerplate code from your Android applications. However, when a lambda expression is simply calling a single method that already has a name, you can cut even more code from your project by using a method reference.

For example, this lambda expression is really just redirecting work to an existing handleViewClick method:

In this scenario, we can refer to this method by name, using the :: method reference operator. You create this kind of method reference, using the following format:

In our Floating Action Button example, we can use a method reference as the body of our lambda expression:

Note that the referenced method must take the same parameters as the interface—in this instance, that’s View .

You can use the method reference operator ( :: ) to reference any of the following:

A Static Method

If you have a lambda expression that calls a static method:

Then you can turn it into a method reference:

For example, if you had a static method PrintMessage in a MyClass class, then your method reference would look something like this:

An Instance Method of a Specific Object

This is an instance method of an object that’s known ahead of time, allowing you to replace:

So, if you had the following lambda expression:

Then introducing a method reference would give you the following:

An Instance Method of an Arbitrary Object of a Particular Type

This is an instance method of an arbitrary object that will be supplied later, and written in the following format:

Constructor References

Constructor references are similar to method references, except that you use the keyword new to invoke the constructor. For example, Button::new is a constructor reference for the class Button , although the exact constructor that’s invoked depends on the context.

Читайте также:  Как открыть root права андроида

Using constructor references, you can turn:

For example, if you had the following MyInterface interface:

Then you could use constructor references to create new Student instances:

It’s also possible to create constructor references for array types. For example, a constructor reference for an array of int s is int[]::new .

Add Default Methods to Your Interfaces

Prior to Java 8, you could only include abstract methods in your interfaces (i.e. methods without a body), which made it difficult to evolve interfaces, post-publication.

Every time you added a method to an interface definition, any classes that implemented this interface would suddenly be missing an implementation. For example, if you had an interface ( MyInterface ) that was used by MyClass , then adding a method to MyInterface would break compatibility with MyClass .

In the best case scenario where you were responsible for the small number of classes that used MyInterface , this behaviour would be annoying but manageable—you’d just have to set aside some time to update your classes with the new implementation. However, things could become much more complicated if a large number of classes implemented MyInterface , or if the interface was used in classes that you weren’t responsible for.

While there were a number of workarounds for this problem, none of them were ideal. For example, you could include new methods in an abstract class, but this would still require everyone to update their code to extend this abstract class; and, while you could extend the original interface with a new interface, anyone who wanted to use these new methods would then need to rewrite all their existing interface references.

With the introduction of default methods in Java 8, it’s now possible to declare non-abstract methods (i.e. methods with a body) inside your interfaces, so you can finally create default implementations for your methods.

When you add a method to your interface as a default method, any class that implements this interface doesn’t necessarily need to provide its own implementation, which gives you a way of updating your interfaces without breaking compatibility. If you add a new method to an interface as a default method, then every class that uses this interface but doesn’t provide its own implementation will simply inherit the method’s default implementation. Since the class isn’t missing an implementation, it’ll continue to function as normal.

In fact, the introduction of default methods was the reason that Oracle was able to make such a large number of additions to the Collections API in Java 8.

Collection is a generic interface that’s used in many different classes, so adding new methods to this interface had the potential to break countless lines of code. Rather than adding new methods to the Collection interface and breaking every class that was derived from this interface, Oracle created the default method feature, and then added these new methods as default methods. If you take a look at the new Collection.Stream() method (which we’ll be exploring in detail in part three), you’ll see that it was added as a default method:

Creating a default method is simple—just add the default modifier to your method signature:

Now, if MyClass uses MyInterface but doesn’t provide its own implementation of defaultMethod , it’ll just inherit the default implementation provided by MyInterface . For example, the following class will still compile:

An implementing class can override the default implementation provided by the interface, so classes are still in complete control of their implementations.

While default methods are a welcome addition for API designers, they can occasionally cause a problem for developers who are trying to use multiple interfaces in the same class.

Imagine that in addition to MyInterface , you have the following:

Both MyInterface and SecondInterface contain a default method with exactly the same signature ( defaultMethod ). Now imagine you try to use both of these interfaces in the same class:

At this point you have two conflicting implementations of defaultMethod , and the compiler has no idea which method it should use, so you’re going to encounter a compiler error.

One way to resolve this problem is to override the conflicting method with your own implementation:

The other solution is to specify which version of defaultMethod you want to implement, using the following format:

So if you wanted to call the MyInterface#defaultMethod() implementation, then you’d use the following:

Using Static Methods in Your Java 8 Interfaces

Similar to default methods, static interface methods give you a way of defining methods inside an interface. However, unlike default methods, an implementing class cannot override an interface’s static methods.

If you have static methods that are specific to an interface, then Java 8’s static interface methods give you a way of placing these methods inside the corresponding interface, rather than having to store them in a separate class.

Читайте также:  Dungeon hunter для андроида с кешем

You create a static method by placing the keyword static at the beginning of the method signature, for example:

When you implement an interface that contains a static interface method, that static method is still part of the interface and isn’t inherited by the class implementing it, so you’ll need to prefix the method with the interface name, for example:

This also means that a class and an interface can have a static method with the same signature. For example, using MyClass.staticMethod and MyInterface.staticMethod in the same class won’t cause a compile-time error.

So, Are Interfaces Essentially Just Abstract Classes?

The addition of static interface methods and default methods has led some developers to question whether Java interfaces are becoming more like abstract classes. However, even with the addition of default and static interface methods, there are still some notable differences between interfaces and abstract classes:

  • Abstract classes can have final, non-final, static and non-static variables, whereas an interface can only have static and final variables.
  • Abstract classes allow you to declare fields that are not static and final, whereas an interface’s fields are inherently static and final.
  • In interfaces, all methods that you declare or define as default methods are inherently public, whereas in abstract classes you can define public, protected, and private concrete methods.
  • Abstract classes are classes, and therefore can have state; interfaces cannot have state associated with them.
  • You can define constructors inside an abstract class, something that’s not possible inside Java interfaces.
  • Java only allows you to extend one class (regardless of whether it’s abstract), but you’re free to implement as many interfaces as you require. This means that interfaces typically have the edge when you require multiple inheritance, although you do need to beware the deadly diamond of death!

Apply the Same Annotation as Many Times as You Want

Traditionally, one of the limitations of Java annotations has been that you cannot apply the same annotation more than once in the same location. Try to use the same annotation multiple times, and you’re going to encounter a compile-time error.

However, with the introduction of Java 8’s repeating annotations, you’re now free to use the same annotation as many times as you want in the same location.

In order to ensure your code remains compatible with earlier versions of Java, you’ll need to store your repeating annotations in a container annotation.

You can tell the compiler to generate this container, by completing the following steps:

  • Mark the annotation in question with the @Repeatable meta-annotation (an annotation that’s used to annotate an annotation). For example, if you wanted to make the @ToDo annotation repeatable, you’d use: @Repeatable(ToDos.class) . The value in parentheses is the type of container annotation that the compiler will eventually generate.
  • Declare the containing annotation type. This must have an attribute that’s an array of the repeating annotation type, for example:

Attempting to apply the same annotation multiple times without first declaring that it’s repeatable will result in an error at compile-time. However, once you’ve specified that this is a repeatable annotation, you can use this annotation multiple times in any location where you’d use a standard annotation.

Conclusion

In this second part of our series on Java 8, we saw how you can cut even more boilerplate code from your Android projects by combining lambda expressions with method references, and how to enhance your interfaces with default and static methods.

In the third and final installment, we’ll be looking at a new Java 8 API that lets you process huge amounts of data in a more efficient, declarative manner, without having to worry about concurrency and thread management. We’ll also be tying together a few of the different features we’ve discussed throughout this series, by exploring the role that Functional Interfaces have to play in lambda expressions, static interface methods, default methods, and more.

And finally, even though we’re still waiting for Java 8’s new Date and Time API to officially arrive on Android, I’ll show how you can start using this new API in your Android projects today, with the help of some third-party libraries.

In the meantime, check out some of our other posts on Java and Android app development!

Источник

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

Интерфейсы в Java 8 потерпели наибольшие изменения. Например, в Java 7 в интерфейсах мы могли объявлять только методы. Но начиная с Java 8 мы можем использовать в интерфейсах стандартные методы (default methods) и статические методы (static methods). Подробнее о нововведениях в интерфейсах читайте под катом

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

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

Читайте также:  Смарт приставка тв mx9 smart box tv android 1gb 8gb описание

Методы по умолчанию (default methods) в интерфейсах Java 8

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

Обратите внимание, что в представленном выше интерфейсе метод log(String str) является методом по умолчанию. Теперь, когда какой-либо класс будет реализовывать интерфейс Interface1, не является обязательным обеспечить реализацию методов по умолчанию (в нашем случае — это метод log(String str) ). Функционал с методами по умолчанию очень поможет нам в будущем, когда множество классов уже будут реализовывать этот интерфейс.

А теперь давайте рассмотрим еще один интерфейс:

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

Все дело в том, что если класс реализует как Interface 1 , так и Interface2 и не реализовывает общий метод по умолчанию, то компилятор не может решить что выбрать.

Наследование нескольких интерфейсов является неотъемлемой частью Java, поэтому теперь в Java 8 нам нужно следить за тем, чтобы эта проблема не возникала и в интерфейсах. Так что, если класс реализует оба вышеуказанных интерфейса, то он должен будет обеспечить реализацию метода log(String str) , в противном случае компилятор будет бросать ошибки.

Сейчас давайте посмотрим пример класса, который реализует оба интерфейса и обеспечивает реализацию метода по умолчанию:

Коротко о главном. Методы по умолчанию в интерфейсах

  1. Методы по умолчанию помогаю реализовывать интерфейсы без страха нарушить работу других классов.
  2. Методы по умолчанию в Java 8 позволяют избежать создания служебных классов, так как все необходимые методы могут быть представлены в самих интерфейсах.
  3. Методы по умолчанию дают свободу классам выбрать метод, который нужно переопределить.
  4. Одной из основных причин внедрения методов по умолчанию является возможность коллекций (в Java 8, конечно) использовать лямбда-выражения.
  5. Если какой-либо класс в иерархии имеет метод с той же сигнатурой, то методы по умолчанию становятся неактуальными. Метод по умолчанию не может переопределить метод класса java.lang.Object . Аргументация очень проста: это потому, что объект является базовым классом для всех Java-классов. Таким образом, даже если у нас есть методы класса Object , определенные в качестве методов по умолчанию в интерфейсах, это будет бесполезно, потому что всегда будет использоваться метод класса объекта. Вот почему, чтобы избежать путаницы, мы не можем писать стандартные методы, которые переопределяли бы методы класса Object .

Статические методы в интерфейсах

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

Давайте посмотрим использование статических методов на простом примере:

Как видим в примере выше, мы использовали тернарный оператор для уменьшения количества кода.

А теперь давайте рассмотрим класс, который реализует интерфейс выше:

Обратите внимание, что i sNull(String str) является простым методом класса, и он не переопределяет метод интерфейса. А что будет, если мы добавим аннотацию @Override к методу isNull() ? Это приведет к ошибке.

Результатом выполнения приведенной выше программы является следующее:

А теперь давайте изменим в интерфейсе ключевое слово static на default . Результат выполнения представлен ниже:

Статические методы видны только для методов интерфейса. Если мы удалим метод isNull() из класса MyDataImpl , то уже не сможем использовать его для объекта MyDataImpl . Однако, как и другие статические методы, мы можем использовать имя класса для доступа к ним.

Например, так писать можно:

Коротко о главном. Статические методы в интерфейсах

  1. Статические методы в интерфейсе являются частью интерфейса, мы не можем использовать его для объектов класса реализации.
  2. Статические методы в интерфейсе хороши для обеспечения вспомогательных методов, например, проверки на null, сортировки коллекций и т.д.
  3. Статические методы в интерфейсе помогают обеспечивать безопасность, не позволяя классам, которые реализуют интерфейс, переопределить их.
  4. Мы не можем определить статические методы для методов класса Object , потому что получим ошибку компиляции: «This static method cannot hide the instance method from Object«. Это потому, что в Java так делать нельзя 🙂 . То есть Object является базовым классом для всех классов и мы не можем использовать статический метод и еще такой метод с одинаковой сигнатурой.
  5. Мы можем использовать статические методы интерфейса, чтобы не создавать вспомогательные классы, то есть переместить все статические методы в соответствующий интерфейс. Такой метод легко использовать и быстро находить.

Функциональные интерфейсы

В завершение статьи хотел бы дать краткое введение в функциональные интерфейсы.

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

В Java 8 была введена новая аннотация @FunctionalInterface для обозначения интерфейса, функциональным интерфейсом. Новая аннотация @FunctionalInterface добавляется для того, чтобы избежать случайного добавления абстрактных методов в функциональный интерфейс. Она не обязательна, но является хорошей практикой написания кода.

Функциональные интерфейсы — это долгожданная фича Java 8, потому что это позволяет нам использовать лямбда-выражения для создания экземпляра таких интерфейсов. Был добавлен новый пакет java.util.function с множеством функциональных интерфейсов.

Мы рассмотрим функциональные интерфейсы и лямбда-выражения в будущих постах. Следите за обновлениями раздела Особенности и нововведения Java 8.

Источник

Оцените статью