Classes Anônimas em java

package classesAnonimas;

/**
 *
 * @author isaura
 */

// Declaração de interface
public interface Aula 
{
    // Declaração do metódo estudar::::
    public void estudar();
    
}



//import classesAnonimas.Aula;



/**
 *
 * @author isaura
 */
public class Test1 
{
    
    public static void main(String[] args) 
    {
        // Classe  anônima, onde é possível instanciar interfaces e ao mesmo tempo criar os methods declarados nela
        
         Aula aula = new Aula()
        {

            @Override
            public void estudar()
            {
             System.out.println("Estou estudando!");
            }
        
        };
         
         aula.estudar();
    }
    
}
3 curtidas

Na verdade você não está instanciando uma interface.
Está instanciando uma classe sem nome, por isso se chama anônima, que implementa a interface.
É só a sintaxe que faz parecer que está instanciando a interface.
No caso desse exemplo, nem precisaria criar a classe anônima, como a interface só tem um método, poderia usar expressão lâmbda, assim:

Aula aula = () -> System.out.println("Estou estudando!");
2 curtidas

Classes com um único método declarado geralmente são identificadas como interfaces funcionais, estas interfaces permitem serem implementadas diretamente dado que possuem somente um único método declarado.

1 curtida

Respeito a sua ideia, mas independentemente do nome que elas tenham, não deixam de ser interfaces, em declarações e utilizações normais, as interfaces não são instanciadas com a palavra reservada new.
Mas no uso de classes anónimas é possível…

1 curtida

Foi simplesmente um exemplo, podem ser declaradas vários métodos, dentro da interface e instanciar as interfaces e criar os métodos normalmente…

1 curtida

Não é minha ideia, é um fato: uma classe anônima não é uma interface.

Tanto que você só pode declarar métodos concretos dentro dela e pode criar mais métodos com assinaturas que não estão presentes na interface que ela implementa.
Entretanto esses métodos só serão acessíveis dentro dela, qualquer código cliente que receber uma instância da classe anônima não terá acesso aos métodos que não pertencem à interface que ela implementa.

Só estou tentando fazer você entender que isso não é instanciar uma interface e sim instanciar uma classe sem nome, que implementa a sua interface.

A sintaxe de instanciação de classes anônimas funciona para criar tanto classes que implementam uma interface quanto classes que estendem outras classes abstratas ou concretas.
:slight_smile:

2 curtidas

Entendo perfeitamente, a Loiane Gronner havia ensinado-me assim…Mas muito obrigada, estou disposta a aprender sempre…

1 curtida

Essa não é uma boa prática, este conceito é aplicável em interfaces funcionais, ou seja, interfaces que possuem apenas um único método a ser implementado, para interfaces com mais de um método o ideal é ter uma classe concreta que implemente esta interface!
Só para reforçar, a “instância” não é da interface, mas sim de uma classe anônima como já foi comentado no post, interfaces não podem serem instanciadas!

2 curtidas

Bem entendido!!

Esta informação esta errada.

Chamamos de interfaces funcionais as interfaces que possuem apenas um método.

Classes, mesmo as abstratas, com apenas um método, mesmo que abstrato, não tem nada de especial e não recebem qualquer nome especial.

Veja mais: https://docs.oracle.com/javase/specs/jls/se15/html/jls-9.html#jls-9.8

Dessa forma, não é possível usar uma expressão lambda em locais onde uma classe é esperada, já que toda expressão lambda resulta numa instancia de uma interface funcional.

Experimente compilar o código abaixo:

interface Interface { void doSomething(); }

abstract class AbstractClass { abstract void doSomething(); }

public class Main {
  static void testA(Interface e) { e.doSomething(); }

  static void testB(AbstractClass e) { e.doSomething(); }

  public static void main(String... args) {
    testA(() -> System.out.println("testA"));
    testB(() -> System.out.println("testB"));
  }
}

Vc verá que um erro de compilação ocorrerá com a seguinte mensagem:

Main.java:12: error: incompatible types: AbstractClass is not a functional interface
    testB(() -> System.out.println("testB"));
    ^

E só reforçando a informação dos colegas:

Quando vc cria uma classe anônima usando uma interface, na prática, o compilador irá criar automáticamente uma nova classe que implementa aquela interface.

E se usar uma classe, o compilador criará uma nova classe que a extende.

Experimente compilar o código abaixo:

// Main.java
interface Interface { void doSomething(); }

class Class { void doSomething() {} }

public class Main {
  public static void main(String... args) {
    new Interface() {
      @Override public void doSomething() {
        System.out.println("doSomething");
      }
    };

    new Class() {};
  }
}

Vc verá que o compilador gerará 5 arquivos com a extensão .class.

  • Class.class
  • Interface.class
  • Main$1.class
  • Main$2.class
  • Main.class

Agora execute o seguinte comando:

javap -c 'Main$1'

O resultado será parecido com este:

Compiled from "Main.java"
class Main$1 implements Interface {
  Main$1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public void doSomething();
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String doSomething
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

Por último execute o seguinte comando:

javap -c 'Main$2'

O resultado será parecido com este:

Compiled from "Main.java"
class Main$2 extends Class {
  Main$2();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method Class."<init>":()V
       4: return
}

E vejam como 2 novas classes são criadas, Main$1 e Main$2, a primeira implementando Interface e a segunda extendendo Class.

1 curtida

Mas foi exatamente o que eu disse, interfaces funcionais são identificadas por possuírem somente um método!
Talvez eu tenha me expressado errado ou você não tenha entendido.

Não, o que vc disse foi “Classes com um único método declarado geralmente são identificadas como interfaces funcionais”.

Tá nesta mensagem aqui, ó: Classes Anônimas em java

Exatamente, ainda reafirmei em outra resposta mais abaixo!

Não compreendi sua linha de pensamento.

Talvez a frase do @Jonathan_Medeiros ficou confusa, mas acredito que ele quis explicar que nos cenários onde se criam classes que implementam um único método, essas classes estão implementando interfaces funcionais, nesse caso, não seria necessário criar a classe e sim implementar diretamente a interface funcional, seja através de classe anônima ou expressão lâmbda.

2 curtidas

Exatamente isso!
Peço desculpas se a forma como eu falei acabou ficando confusa, o meu intuito foi somente colaborar com o entendimento.

2 curtidas