Cada nova versão do Java é diferente das anteriores. Aqui está um exemplo das alterações do material que abordamos: Antes do Java 5, não havia
Da mesma forma, Java 8 é visivelmente diferente de Java 7. A maioria de nossas palestras é escrita na 7ª versão da linguagem, mas, é claro, não iremos ignorar inovações importantes. Já que estamos falando sobre interfaces nesta palestra, vamos dar uma olhada em um método update - default em interfaces . Você já sabe que uma interface não implementa . Sua tarefa é descrever qual comportamento todos os objetos que o implementam devem ter . Mas muitas vezes os desenvolvedores encontraram situações em que a implementação de um método em todas as classes era a mesma. Vejamos nosso exemplo de carro antigo:
enum
's na linguagem.
public interface Car {
public void gas();
public void brake();
}
public class Sedan implements Car {
@Override
public void gas() {
System.out.println("Газ!");
}
@Override
public void brake() {
System.out.println("Тормоз!");
}
}
public class Truck implements Car {
@Override
public void gas() {
System.out.println("Газ!");
}
@Override
public void brake() {
System.out.println("Тормоз!");
}
}
public class F1Car implements Car {
@Override
public void gas() {
System.out.println("Газ!");
}
@Override
public void brake() {
System.out.println("Тормоз!");
}
}
Qual você acha que é o principal problema desse código? Você provavelmente notou que escrevemos vários códigos iguais! Este problema é comum em programação e deve ser evitado. Outra coisa é que antes do lançamento do Java 8 não havia opções de soluções especiais. Quando esta versão foi lançada, tornou-se possível definir métodos padrão e implementá-los diretamente na interface! Veja como isso é feito:
public interface Car {
public default void gas() {
System.out.println("Газ!");
}
public default void brake() {
System.out.println("Тормоз!");
}
}
public class Sedan implements Car {
}
public class Truck implements Car {
}
public class F1Car implements Car {
}
Agora os métodos gas()
e brake()
, que eram iguais para todas as máquinas, estão incluídos na interface e não é necessário código duplicado. Além disso, 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 método gas()
, mas apenas 99 delas tiverem o mesmo comportamento? Isso estraga tudo e o método padrão não funcionará neste caso? Claro que não :) Os métodos padrão de interfaces podem ser substituídos.
public class UnusualCar implements Car {
@Override
public void gas() {
System.out.println("Эта машина газует по-другому!");
}
@Override
public void brake() {
System.out.println("Эта машина тормозит по-другому!");
}
}
Todos os outros 99 tipos de máquinas implementarão o método padrão, e a classe UnusualCar
- a exceção - não prejudicará o quadro geral e determinará com calma seu 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 isso; vamos examiná-las em detalhes em uma palestra separada. Em outras linguagens, por exemplo, em C++, é o contrário. Sem herança múltipla, surge um problema sério: o mesmo objeto pode ter diversas características e “comportamentos” diferentes. Um exemplo de vida: para os nossos pais somos filhos, para os professores somos alunos, para os médicos somos pacientes. Na vida, desempenhamos papéis diferentes e, portanto, nos comportamos de maneira diferente: obviamente falaremos com os professores de maneira diferente do que com amigos próximos. Vamos tentar traduzir esta situação em código. Vamos imaginar que temos duas classes: Lagoa e Aviário. Para um lago você precisa de pássaros nadadores, e para um aviário você precisa de pássaros voadores. Para fazer isso, criamos duas classes base – FlyingBird
e Waterfowl
.
public class Waterfowl {
}
public class FlyingBird {
}
Assim, enviaremos para o aviário aquelas aves cujas classes são herdadas de FlyingBird
, e para o lago - aquelas que descendem de Waterfowl
. Tudo parece simples. Mas o que faremos se precisarmos identificar o pato em algum lugar? Ela nada e voa. Mas não temos herança múltipla. Felizmente, Java fornece múltiplas implementações de interfaces. Se uma classe não pode herdar de vários pais, é fácil implementar várias interfaces! Nosso pato pode voar e nadar :) Basta usar interfaces FlyingBird
ao invés Waterfowl
de classes para alcançar o resultado desejado.
public class Duck implements FlyingBird, Waterfowl {
//методы обоих интерфейсов легко объединяются в одном классе
@Override
public void fly() {
System.out.println("Летим!");
}
@Override
public void swim() {
System.out.println("Плывем!");
}
}
Graças a isso, nosso programa mantém um gerenciamento flexível de classes e, em combinação com a implementação de métodos padrão, nossa capacidade de definir o comportamento dos objetos torna-se quase ilimitada! :)
GO TO FULL VERSION