Programação orientada a objetos: classes abstratas e interfaces

interface_abstract_classes

Continuamos com nosso curso de programação . Neste artigo, aprofundaremos um pouco a questão da reutilização de código. Ao usar a herança, é muito comum que, ao estender a funcionalidade de uma classe, a classe da qual estendemos, a superclasse ou a classe pai, não faça mais sentido instancia-la. Em nosso exemplo de fazenda, lembramos que tínhamos o tipo Animal e os subtipos Porco e Vaca que se estendiam a partir dele.

Se olharmos para ele, é provável que em nosso aplicativo não instancemos novamente a classe Animal, porque a funcionalidade já está sendo gerada quando instanciamos as classes Cow e Pig . Podemos ver tudo isso de um ponto de vista diferente com um exemplo.

Imagine que todos os animais em nossa fazenda tenham que comer, tenham um método de alimentação que, dependendo do subtipo de Animal e seu peso, coma mais ou menos. Então, como implementamos esse método?

Uma primeira opção seria declarar o método na classe Animal, e que todas as outras classes herdam e substituem esse método, mas como o implementamos? Vazio

public void comer(){

}

Não faz muito sentido fazer isso. Quando usamos herança, é muito provável que um método precise ser declarado, mas que a implementação desse método não faça sentido , esse é o caso. O que realmente devemos fazer é enviar uma mensagem da classe Animal para suas subclasses e que eles são responsáveis ​​por implementá-la . Java resolve esse problema declarando o método como abstrato .

Métodos abstratos

Em Java, os métodos abstratos não têm nenhum tipo de implementação. Para declará-los, basta definir um cabeçalho de método adicionando a palavra-chave abstract . Vamos levar tudo isso ao nosso exemplo.

Vamos começar declarando nosso método abstrato em nossa classe Animal:

public abstract void comer();

Se você observar o Eclipse, seremos notificados de duas falhas, embora basicamente seja uma:
error_abstract_method

Relacionado:  Programação orientada a objetos: níveis de acesso

O que isso nos diz é que removemos o método ou definimos a classe Animal como abstrata . Se formos às soluções propostas pelo Eclipse, ele nos oferece duas opções:
solucion_metodo_abstract

Selecionamos a segunda opção, transformamos a classe Animal em abstrata. Uma classe com (pelo menos) um método abstrato é uma classe abstrata. Uma classe abstrata é uma classe cujo objetivo é servir como uma superclasse para outras classes

  1. Ou para generalização (polimorfismo)
  2. Ou para reutilização de código, por exemplo, extensão (herança)

Se olharmos agora, teremos pelo menos essas três falhas:
Absolute_class_Problems

  • Diz-nos que não podemos instanciar a classe Animal.

Por enquanto, não vamos resolver esse problema, deixaremos para depois. Agora, para não ignorarmos o erro, vamos para a classe Farm e eliminamos o método readConsola e todas as chamadas feitas desse método.

  • Devemos implementar o método de comer tanto na classe Cow quanto na classe Pig. Em todas essas subclasses da classe Animal.

Para resolvê-lo, vamos às classes Cow e Pig e adicionamos os seguintes métodos.

Na classe Pig, adicionamos:

@Override
public void comer() {
    System.out.println("El cerdo comerá: "+getPeso()*10+" kg de pienso.");
}   

Na classe Cow, adicionamos:

@Override
 public void comer() {
    System.out.println("La vaca comerá: "+getPeso()*8+" kg de pienso.");
}

Se você observar as classes abstratas, forçará as subclasses a redefinir os métodos declarados como abstratos . Caso contrário, as subclasses também seriam abstratas. Em Java, é possível declarar uma classe abstrata sem métodos abstratos, pois pode herdar os métodos abstratos da superclasse. É provável que indique que a criação de subclasses (uma generalização) é necessária.

Com isso, já temos uma classe Animal que implementou os métodos comuns que todas as suas subclasses terão e uma mensagem (o método eat) que será implementada pelas subclasses. Mas … e se quisermos que nossa classe Cow seja herdada de outra classe? Em Java, podemos herdar apenas uma classe (em C ++, por exemplo, podemos exagerar). Como posso enviar mensagens de uma classe para outra? em Java, essa função é determinada pelas interfaces .

Relacionado:  Qual é o padrão de design composto?

Interfaces

Para compensar a falta de herança múltipla, Java suporta o conceito de Interface . Uma interface é definida como o conjunto de mensagens que uma classe oferece a seus clientes (público). Em Java, esse conceito é oferecido como um tipo. Portanto, uma interface Java é um conjunto de declarações de método, sem implementação. Em Java, eles têm as seguintes características:

  • As interfaces podem ser declaradas como públicas ou não (pacote)
  • Todos os seus métodos são abstratos (não é necessário colocar a palavra resumo)
  • Todos os seus métodos são públicos (não é necessário publicá-lo)
  • As interfaces não têm construtores.
  • Somente atributos com final estático público são permitidos.
  • Uma interface pode herdar de outras interfaces.
  • Uma classe pode herdar (implementar) várias interfaces .

Vamos ver tudo isso com um exemplo. Suponha que a classe Cow implemente uma interface chamada “Leitoso”. Primeiro, definimos a interface como:

public interface Ordeñable {
void ordeñar();
}

Nós adicionamos o seguinte código na classe Cow

public class Vaca extends Animal implements Ordeñable {

public Vaca(String nombre) {
    super(nombre);
}

@Override
public void comer() {
    System.out.println("La vaca comerá: " + getPeso() * 8
            + " kg de pienso.");
}

@Override
public void ordeñar() {
    System.out.println("Estoy ordeñando la vaca: " + getNombre());
}

}

Se olharmos, usamos a palavra reservada implementa e redefinimos os métodos que a interface declarou.

Em resumo

A generalização múltipla é frequentemente necessária. Como o Java não fornece herança múltipla, as interfaces são usadas. Vamos sempre enfatizar que:

  • Uma classe Java pode implementar várias interfaces.
  • A implementação de uma interface não tem nada a ver com herança (a falta de implementação é herdada porque cada método é abstrato).

Um uso comum das interfaces é separar uma funcionalidade do seu aplicativo, pois uma interface define uma funcionalidade (que deve ser exclusiva). Cada classe que implementa essa interface define as possíveis implementações.

Relacionado:  Programação orientada a objetos: listas

Vamos terminar sempre tendo em mente que:

  • Os métodos abstratos definem as mensagens que podem ser passadas para um objeto.
  • Classes abstratas são superclasses parcialmente implementadas.
  • A herança múltipla não é suportada em Java, mas temos interfaces que permitem múltiplas generalizações.
  • Uso comum de classes abstratas para reutilizar código por herança.
  • Uso comum de interfaces para enviar mensagens que devem ser implementadas.

Uma forma comum de programação Java é:

  1. Sempre use interfaces para generalizar
  2. Use apenas classes abstratas para reutilizar a implementação da interface (parcial)

Aqui você tem o código fonte usado.

 

Você pode estar interessado:

Deixe um comentário