Sobes.tech
Junior

Como você escreveria um método de extensão em Java?

sobes.tech IA

Resposta da IA

No Java, não é possível escrever um método de extensão verdadeiro no mesmo sentido que em Kotlin ou C#. A principal razão é a ausência de açúcar sintático direto para adicionar métodos às classes existentes, mantendo o princípio de encapsulação.

No entanto, é possível alcançar um comportamento semelhante usando os seguintes padrões:

  1. Método auxiliar estático: Cria-se uma classe estática com métodos estáticos públicos que aceitam uma instância da classe que queremos "estender".

    // Exemplo de classe que queremos "estender"
    public class MyClass {
        private String name;
    
        public MyClass(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    
    // Classe estática com "método de extensão"
    public class MyClassExtensions {
        // Método que simula um método de extensão
        public static void printNameUpperCase(MyClass obj) {
            if (obj != null) {
                System.out.println(obj.getName().toUpperCase());
            }
        }
    }
    

    Uso:

    // Uso do "método de extensão"
    MyClass myObj = new MyClass("test");
    MyClassExtensions.printNameUpperCase(myObj); // Chama o método estático
    
  2. Padrão Decorador (envoltório): Cria-se uma nova classe que envolve a classe existente e adiciona um comportamento novo.

    // Classe decoradora
    public class MyClassDecorator {
        private MyClass original; // Referência ao objeto original
    
        public MyClassDecorator(MyClass original) {
            this.original = original;
        }
    
        // Método que simula um método de extensão
        public void printNameUpperCase() {
            if (original != null) {
                System.out.println(original.getName().toUpperCase());
            }
        }
    
        // Pode-se adicionar métodos que simplesmente delegam a chamada ao objeto original
        public String getName() {
            return original.getName();
        }
    }
    

    Uso:

    // Uso do decorador
    MyClass myObj = new MyClass("another test");
    MyClassDecorator decoratedObj = new MyClassDecorator(myObj);
    decoratedObj.printNameUpperCase(); // Chama o método do decorador
    
  3. Herança: Se a classe não for marcada como final, pode-se criar uma subclasse e adicionar novos métodos. Isso não é um método de extensão no sentido literal, pois você cria um novo tipo, mas é uma das formas de adicionar funcionalidade.

    // Subclasse com novo método
    public class ExtendedMyClass extends MyClass {
    
        public ExtendedMyClass(String name) {
            super(name);
        }
    
        // Novo método na subclasse
        public void printNameUpperCase() {
            System.out.println(getName().toUpperCase());
        }
    }
    

    Uso (funciona apenas com instâncias de ExtendedMyClass):

    // Uso da subclasse
    ExtendedMyClass extendedObj = new ExtendedMyClass("inheritance test");
    extendedObj.printNameUpperCase(); // Chama o método da subclasse
    

A abordagem mais comum para imitar métodos de extensão em Java, especialmente para adicionar funcionalidades utilitárias às classes de bibliotecas existentes, é o uso de métodos auxiliares estáticos. Isso é o mais próximo em espírito dos métodos de extensão de outras linguagens, embora exija chamá-los pelo nome da classe estática.