Diferença entre métodos estáticos e padrão na interface


107

Eu estava aprendendo por meio de interfaces quando percebi que agora você pode definir métodos estáticos e padrão em uma interface.

public interface interfacesample2 {
    public static void method() {
        System.out.println("hello world");
    }

    public default void menthod3() {
        System.out.println("default print");
    }
}

Explique a diferença dos dois e também se houver um exemplo de quando usaríamos isso, seria bom. Um pouco confuso em Interfaces.


4
Você tentou ler sobre métodos estáticos no tutorial Java?
Dawood ibn Kareem

1
Então você perdeu a parte sobre nunca ser capaz de substituir um método estático?
Dawood ibn Kareem

1
não entendi o mesmo em interfaces
Vipin Menon

9
o método estático é um membro estático da Interface, não pode ser sobrescrito (como acontece com a classe), o método padrão é o default implementationde um método que pode ser sobrescrito.
Shail016

2
Apenas me perguntando: por que você nunca aceitou uma resposta aqui?
GhostCat

Respostas:


116

Diferenças entre métodos estáticos e padrão em Java 8:

1) Os métodos padrão podem ser substituídos na implementação da classe, enquanto os estáticos não podem .

2) O método estático pertence apenas à classe Interface, então você só pode invocar o método estático na classe Interface, não na classe que implementa esta Interface, consulte:

public interface MyInterface {
    default void defaultMethod(){
        System.out.println("Default");
    }

    static void staticMethod(){
        System.out.println("Static");
    }    
}

public class MyClass implements MyInterface {

    public static void main(String[] args) {

        MyClass.staticMethod(); //not valid - static method may be invoked on containing interface class only
        MyInterface.staticMethod(); //valid
    }
}

3) Tanto a classe quanto a interface podem ter métodos estáticos com os mesmos nomes e nenhum substitui o outro!

public class MyClass implements MyInterface {

    public static void main(String[] args) {

        //both are valid and have different behaviour
        MyClass.staticMethod();
        MyInterface.staticMethod();
    }

    static void staticMethod(){
        System.out.println("another static..");
    }
}

2
mas por que 'estático'? a que propósito serve no Java 8?
Shashank Vivek

4
O propósito da palavra-chave static não mudou - definir membros de nível de classe: campos, métodos etc. No Java 8, esse comportamento foi expandido para Interfaces, de forma que se tornem mais semelhantes às classes e agora podem substituir a classe na maioria dos cenários.
ferrão

sim, mas ainda podemos ocultar o método estático da interface em vez de sobrescrever, .... eu só acho que ambos cumprem o mesmo purpose( use uma implementação comum ) e resolvem a ambigüidade implementing the logic again in subclass ( sobrescrevendo, ocultando ). a única razão sensata seria a de que [os métodos de interface estática não são herdados] ( stackoverflow.com/questions/25169175/… ) e, portanto, não podemos chamá-los usando uma instância de subclasse.
Amarnath Harish

29

Um método estático é um método que se aplica ao 'namespace' da classe, por assim dizer. Portanto, um staticmétodo foode interface Interfaceé acessado por Interface.foo(). Observe que a chamada de função não se aplica a nenhuma instância particular da interface.

Uma implementação padrão, barpor outro lado, é chamada por

Interface x = new ConcreteClass();
x.bar();

Um staticmétodo de interface não pode saber sobre a thisvariável, mas uma implementação padrão pode.


19

1. explique a diferença dos dois

Os métodos de interface estática são como métodos de classe estáticos (aqui eles pertencem apenas à Interface). Onde, como os métodos de interface padrão fornecem métodos default implementationde interface (que classes de implementação podem override),
mas lembre-se, no caso de uma classe ser a implementing more than one interface with same defaultassinatura de método, então a classe de implementaçãoneeds to override the default method

Você pode encontrar um exemplo simples abaixo (pode DIY para casos diferentes)

public class Test {
    public static void main(String[] args) {
        // Accessing the static member
        I1.hello();

        // Anonymous class Not overriding the default method
        I1 t = new I1() {
            @Override
            public void test() {
                System.out.println("Anonymous test");
            }
        };
        t.test();
        t.hello("uvw");

        // Referring to class instance with overridden default method
        I1 t1 = new Test2();
        t1.test();
        t1.hello("xyz");

    }
}

interface I1 {

    void test();
    //static method
    static void hello() {
        System.out.println("hello from Interface I1");
    }

    // default need not to be implemented by implementing class
    default void hello(String name) {
        System.out.println("Hello " + name);
    }
}

class Test2 implements I1 {
    @Override
    public void test() {
        System.out.println("testing 1234...");
    }

    @Override
    public void hello(String name) {
        System.out.println("bonjour" + name);
    }
}

2. quando usaríamos isso seria bom.

Isso depende da definição do seu problema. Eu diria que os métodos padrão são úteis, se você precisa da mesma implementação para um método em sua especificação em todas as classes desse contrato, ou pode ser usado como Adapterclasses.

aqui está uma boa leitura: /software/233053/why-were-default-and-static-methods-added-to-interfaces-in-java-8-when-we-alread

também abaixo do documento oracle explica os métodos padrão e estáticos para a evolução das interfaces existentes:

Os usuários que possuem classes que implementam interfaces aprimoradas com novos métodos padrão ou estáticos não precisam modificar ou recompilá-los para acomodar os métodos adicionais.

http://docs.oracle.com/javase/tutorial/java/IandI/nogrow.html


Tenho uma dúvida. É possível criar um objeto de uma interface? Seu código tem esta linha: I1 t = new I1 ()
Hackinet

@Hackinet gentilmente leia o comentário java sobre essa declaração. Leia também sobre classes anônimas. Espero que isso ajude você.
Shail016

12

Aqui está a minha opinião:

método estático na interface:

  • Você pode chamá-lo diretamente (InterfacetA.staticMethod ())

  • A subclasse não poderá ser substituída.

  • A subclasse pode ter um método com o mesmo nome de staticMethod

método padrão na interface:

  • Você não pode ligar diretamente.

  • A subclasse será capaz de substituí-lo

Vantagem:

  • Método estático: Você não precisa criar uma classe separada para o método do utilitário.

  • Método padrão: fornece a funcionalidade comum no método padrão.


8

Este link tem alguns insights úteis, listamos alguns deles aqui.

os métodos padrão e estáticos eliminaram as diferenças entre interfaces e classes abstratas .

Métodos padrão de interface :

  • Isso ajuda a evitar classes de utilitário, como todos os métodos de classe de coleções podem ser fornecidos nas próprias interfaces.
  • Ele ajuda a estender as interfaces sem medo de quebrar as classes de implementação.

Métodos estáticos de interface :

  • Eles são parte da interface, não podemos usá-los para objetos de classe de implementação.
  • Ajuda a fornecer segurança, não permitindo que classes de implementação os substituam.

Gostaria de citar outra referência útil .


3

Métodos padrão de interface:

Isso ajuda a evitar classes de utilitário, como todos os métodos de classe de coleções podem ser fornecidos nas próprias interfaces.

Ele ajuda a estender as interfaces sem medo de quebrar as classes de implementação.

Métodos estáticos de interface:

Eles são parte da interface, não podemos usá-los para objetos de classe de implementação.

Ajuda a fornecer segurança, não permitindo que classes de implementação os substituam.

Agora, como método estático fornecendo segurança. Vamos ver um exemplo.

interface MyInterface {
    /*
     * This is a default method so we need not to implement this method in the implementation classes
     */
    default void newMethod() {
        System.out.println("Newly added default method in Interface");
    }

    /*
     * This is a static method. Static method in interface is similar to default method except that we cannot override them in the implementation classes. Similar to default methods, we need to implement these methods in implementation classes so we can safely add them to the existing interfaces.
     */
    static void anotherNewMethod() {
        System.out.println("Newly added static method in Interface");
    }

    /*
     * Already existing public and abstract method We must need to implement this method in implementation classes.
     */
    void existingMethod(String str);
}

public class Example implements MyInterface {
    // implementing abstract method
    public void existingMethod(String str) {
        System.out.println("String is: " + str);
    }

    public void newMethod() {
        System.out.println("Newly added default method in Class");
    }

    static void anotherNewMethod() {
        System.out.println("Newly added static method in Class");
    }

    public static void main(String[] args) {
        Example obj = new Example();

        // calling the default method of class
        obj.newMethod();
        // calling the static method of class

        obj.anotherNewMethod();

        // calling the static method of interface
        MyInterface.anotherNewMethod();

        // calling the abstract method of interface
        obj.existingMethod("Java 8 is easy to learn");

    }
}

Aqui, obj.newMethod();imprimir a lógica de implementação da classe significa que podemos alterar a lógica desse método dentro da classe de implementação.

Mas a obj.anotherNewMethod();lógica de implementação da classe de impressão, mas não mudou a implementação da interface. Portanto, se houver qualquer lógica de criptografia-descriptografia escrita dentro desse método, você não poderá alterar.


essa resposta parece que está indo para algum lugar bom, então de repente bum! nenhuma explicação significativa no final. mas não mudou a implementação da interface, o que isso significa?
Amarnath Harish

2

De acordo com os Javadocs da Oracle: http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

Os métodos padrão permitem adicionar novas funcionalidades às interfaces de suas bibliotecas e garantir compatibilidade binária com código escrito para versões anteriores dessas interfaces.

Um método estático é um método associado à classe na qual está definido, e não a qualquer objeto. Cada instância da classe compartilha seus métodos estáticos.

Normalmente, o método estático na interface é usado como métodos auxiliares, enquanto o método padrão é usado como uma implementação padrão para as classes que implementam essa interface.

Exemplo:

interface IDemo {

    //this method can be called directly from anywhere this interface is visible
    static int convertStrToInt(String numStr) {
       return Integer.parseInt(numStr);
    }


    //getNum will be implemented in a class
    int getNum();       

    default String numAsStr() {
       //this.getNum will call the class's implementation
       return Integer.toString(this.getNum());
    }   

}

1

De acordo com o documento Java14 JLS:

Método padrão:

  • É um método de instância declarado em uma interface com o modificador padrão

  • Ele pode ser acessado apenas pela instância da classe de implementação apenas

  • Seu corpo é sempre representado por um bloco, que fornece uma implementação ou comportamento padrão para qualquer classe de implementação sem substituir o método

  • Nunca pode ser estático ou privado

Método estático:

  • Ele pode ser chamado pela interface sem referência a um objeto específico, assim como os métodos estáticos de classe

  • O método estático pode ser privado

  • A classe de implementação não pode acessar o método estático

Vamos entender com a ajuda do código de exemplo abaixo:

            public interface MyInterface {
        
            private void privateMethod() {
                System.out.println("Hi, this is privateMethod");
            }
        
            private static void staticPrivateMethod() {
                System.out.println("Hi, this is staticPrivateMethod");
            }
        
            static void staticMethod() {
                //privateMethod();    // Non-static method cannot be referenced from a static contex
                System.out.println("Hi, this is staticMethod");
                staticPrivateMethod();
            }
        
            default void defaultMethod() {
                System.out.println("Hi, this is defaultMethod");
            }
        
        }
    
    public class MyInterfaceImpl implements MyInterface{
        public static void main(String[] args) {
    
            MyInterface.staticMethod();
            // myInterface.staticMethod(); // Not allowed
    
            MyInterface myInterface = new MyInterfaceImpl();
            myInterface.defaultMethod();
            // MyInterface.defaultMethod(); // Not allowed
    
        }
    }

0

não podemos executar Interfacesample2.menthod3();porque não é um método estático. Para executar method3(), precisamos de uma instância de Interfacesample2interface.

Encontre o seguinte exemplo prático:

public class Java8Tester {
   public static void main(String args[]){
      // Interfacesample2.menthod3(); Cannot make a static reference to the non-static method menthod3 from the type Interfacesample2

      new Interfacesample2(){ }.menthod3();// so in order to call default method we need an instance of interface

       Interfacesample2.method(); // it
   }
}

interface Interfacesample2 {
    public static void method() {
        System.out.println("hello world");
    }

    public default void menthod3() {
        System.out.println("default print");
    }
}

0

Iniciar a interface Java 8 também pode ter um método estático. Como o método estático de uma classe, o método estático de uma interface pode ser chamado usando o nome da interface.

Exemplo

public interface Calculator {
    int add(int a, int b);
    int subtract(int a, int b);

    default int multiply(int a, int b) {
         throw new RuntimeException("Operation not supported. Upgrade to UltimateCalculator");
    }

    static void display(String value) {
        System.out.println(value);
    }
}

A diferença entre o método estático e o método padrão da interface é que o método padrão suporta herança, mas o método estático não. O método padrão pode ser substituído na interface de herança.

Aqui está uma boa leitura sobre o método padrão da interface e o método estático. Método padrão de interface em Java 8


0

Todas as boas respostas aqui. Eu gostaria de adicionar outro uso prático da função estática na interface. A dica vem do livro - Effective Java, 3rd Edition de Joshua Bloch no Capítulo 2: Criando e destruindo objeto.

Static functions can be used for static factory methods. 

Os métodos de fábrica estáticos são métodos que retornam um objeto. Eles funcionam como construtores. Em casos específicos, o método de fábrica estático fornece código mais legível do que usar o construtor.

Citando o livro - Effective Java, 3rd Edition de Joshua Bloch

Antes do Java 8, as interfaces não podiam ter métodos estáticos. Por convenção, os métodos de fábrica estáticos para uma interface chamada Type foram colocados em uma classe complementar não instável (Item 4) chamada Types.

O autor dá um exemplo de coleções onde esse método de fábrica estático é implementado. Verificando o código, Josh Bloch pode ser visto como o primeiro autor da classe Coleções. Embora Collections seja uma classe e não uma interface. Mas o conceito ainda se aplica.

Por exemplo, o Java Collections Framework tem quarenta e cinco implementações de utilitários de suas interfaces, fornecendo coleções não modificáveis, coleções sincronizadas e assim por diante. Quase todas essas implementações são exportadas por meio de métodos de fábrica estáticos em uma classe não instável (java.util.Collections). As classes dos objetos retornados são todas não públicas.

Além disso, ele explica que a API não é apenas menor, ela ajuda na legibilidade do código e na facilidade da API.

Não é apenas o volume da API que é reduzido, mas também o peso conceitual: o número e a dificuldade dos conceitos que os programadores devem dominar para usar a API. O programador sabe que o objeto retornado possui precisamente a API especificada por sua interface, portanto, não há necessidade de ler a documentação da classe adicional para a classe de implementação.

Aqui está um dos métodos estáticos da classe java.util.Collections:

public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
    return new UnmodifiableCollection<>(c);
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.