CodeGym /Cursos /All lectures for PT purposes /Métodos padrão em interfaces

Métodos padrão em interfaces

All lectures for PT purposes
Nível 1, Lição 55
Disponível
Cada nova versão do Java difere das anteriores. Como exemplo dessa mudança do material que abordamos, a linguagem não existia enumsantes do Java 5.
Métodos padrão em interfaces - 1
Da mesma forma, o Java 8 é visivelmente diferente do Java 7. Não vamos ignorar inovações importantes, é claro. Já que estamos falando sobre interfaces nesta lição, vamos considerar uma atualização da linguagem: métodos padrão em interfaces . Você já sabe que uma interface não implementa comportamento . Sua finalidade é descrever qual comportamento deve existir em todos os objetos que implementam a interface . Mas os desenvolvedores frequentemente encontravam situações em que a implementação de um método era a mesma em todas as classes. Vejamos nosso exemplo de carro antigo:

public interface Car {

   public void gas();
  
   public void brake();
}
public class Sedan implements Car {

   @Override
   public void gas() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class Truck implements Car {

   @Override
   public void go() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class F1Car implements Car {
   @Override
   public void go() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}
Qual você acha que é o principal problema com esse código? Você provavelmente notou que escrevemos um monte de código duplicado! Este é um problema comum na programação e deve ser evitado. Outra questão é que não havia soluções específicas antes do lançamento do Java 8. Quando essa versão foi lançada, tornou-se possível definir métodos padrão e implementá-los diretamente dentro de uma interface! Veja como fazer:

public interface Car {

   public default void gas() {
       System.out.println("Gas!");
   }

   public default void brake() {
       System.out.println("Brake!");
   }
}

public class Sedan implements Car {

}

public class Truck implements Car {

}

public class F1Car implements Car {

}
Agora os métodos gas()e brake(), que eram os mesmos para todos os carros, foram movidos para a interface, eliminando a necessidade de código duplicado. E os métodos estão disponíveis em cada uma das aulas!

public class Main {

   public static void main(String[] args) {

       F1Car f1Car = new F1Car();
       Sedan sedan = new Sedan();
       Truck truck = new Truck();
       truck.gas();
       sedan.gas();
       f1Car.brake();
   }
}
E se houver 100 classes com um gas()método, mas apenas 99 delas tiverem o mesmo comportamento? Isso estraga tudo? Um método padrão não funcionará neste caso? Claro que não :) Os métodos de interface padrão podem ser substituídos.

public class UnusualCar implements Car {
   @Override
   public void go() {
       System.out.println("This car accelerates differently!");
   }

   @Override
   public void brake() {
       System.out.println("This car slows down differently!");
   }
}
Todos os outros 99 tipos de carros empregarão o método padrão, enquanto o UnusualCarclasse é uma exceção. Sem estragar o quadro geral, ele definirá com calma seu próprio comportamento. Herança múltipla em interfaces. Como você já sabe, não existe herança múltipla em Java. Há muitas razões para isto. Vamos considerá-los em detalhes em uma lição separada. Em outras linguagens, como C++, a situação é inversa. Nenhuma herança múltipla apresenta um grande desafio, pois um mesmo objeto pode ter várias características e comportamentos diferentes. Por exemplo, somos filhos para nossos pais, alunos para nossos professores e pacientes para nossos médicos. Na vida real, desempenhamos vários papéis e, portanto, nos comportamos de maneira diferente: obviamente, interagimos com os professores de maneira diferente do que com amigos próximos. Vamos tentar traduzir essa situação em código. Vamos imaginar que temos duas classes: Pond e Aviary. Um lago precisa de pássaros nadadores, enquanto um aviário precisa de pássaros voadores. Para representar isso, criamos duas classes base: FlyingBirde Waterfowl.

public class Waterfowl {
}

public class FlyingBird {
}
Assim, enviaremos as aves que herdam FlyingBirdpara o aviário, enquanto as que derivam Waterfowlirão para a lagoa. Tudo parece simples. Mas o que devemos fazer se precisarmos definir um pato em algum lugar? Os patos nadam e voam. Mas não temos herança múltipla. Felizmente, o Java oferece suporte a várias implementações de interfaces. Se uma classe não pode herdar vários pais, é fácil implementar várias interfaces! Nosso pato pode ser tanto um pássaro voador quanto um pássaro nadador :) Para atingir o resultado desejado, tudo o que precisamos fazer é criar FlyingBirdinterfaces Waterfowlem vez de classes.

public class Duck implements FlyingBird, Waterfowl {

   // Methods of both interfaces combine easily into one class
  
   @Override
   public void fly() {
       System.out.println("Flying!");
   }

   @Override
   public void swim() {

       System.out.println("Swimming!");
   }
}
Isso significa que nosso programa mantém a capacidade de gerenciar classes de forma flexível. Quando combinamos isso com métodos padrão, nossa capacidade de determinar o comportamento dos objetos torna-se quase ilimitada! :)
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION