ti-enxame.com

Qual o sentido de usar métodos abstratos?

Qual o sentido de usar "métodos abstratos"? Uma classe abstrata não pode ser instanciada, mas e os métodos abstratos? Eles estão aqui apenas para dizer "você precisa me implementar" e, se os esquecermos, o compilador gera um erro?

Isso significa outra coisa? Também li algo sobre "não precisamos reescrever o mesmo código", mas na classe abstrata, apenas "declaramos" o método abstrato, portanto, teremos que reescrever o código na classe filho.

Você pode me ajudar a entender um pouco mais? Eu verifiquei os outros tópicos sobre "classe/métodos abstratos", mas não encontrei uma resposta.

31
Paul

Além do lembrete de que você deve implementá-lo, a grande vantagem é que qualquer pessoa que referencie o objeto por seu tipo de classe abstrata (incluindo this na própria classe abstrata) pode usar o método.

Por exemplo, digamos que temos uma classe responsável por tomar o estado e manipulá-lo de alguma maneira. A classe abstrata será responsável por obter a entrada, convertê-la em long (por exemplo) e combinar esse valor com o valor anterior de alguma forma - esse "de alguma maneira" é o método abstrato. A classe abstrata pode ser algo como:

public abstract class StateAccumulator {
    protected abstract long accumulate(long oldState, long newState);

    public handleInput(SomeInputObject input) {
        long inputLong = input.getLong();
        state = accumulate(state, inputLong);
    }

    private long state = SOME_INITIAL_STATE;
}

Agora você pode definir um acumulador de adição:

public class AdditionAccumulator extends StateAccumulator {
    @Override
    protected long accumulate(long oldState, long newState) {
        return oldState + newState;
    }
}

Sem esse método abstrato, a classe base não teria como dizer "manipular esse estado de alguma forma". Porém, não queremos fornecer uma implementação padrão na classe base, porque isso não significaria muito - como você define uma implementação padrão para "alguém implementará isso"?

Observe que há mais de uma maneira de esfolar um gato. O padrão de estratégia envolveria a declaração de uma interface que declara o padrão accumulate e a transmissão de uma instância dessa interface para a classe base que não é mais abstrata. Em termos de linguagem, é usar composição em vez de herança (você compôs um agregador de adição de dois objetos, um agregador e um somador).

16
yshavit

Digamos que você tenha três impressoras para as quais você precisaria gravar um driver, Lexmark, Canon e HP.

Todas as três impressoras terão os métodos print() e getSystemResource().

No entanto, apenas print() será diferente para cada impressora. getSystemResource() permanece o mesmo nas três impressoras. Você também tem outra preocupação, gostaria de aplicar o polimorfismo.

Portanto, como getSystemResource() é o mesmo para todas as três impressoras, portanto, isso pode ser transferido para a superclasse a ser implementada, em Java, isso pode ser feito via tornando esse resumo na superclasse e tornando Como um método abstrato em uma superclasse, a própria classe também precisa ser abstrata.

public abstract class Printer{
  public void getSystemResource(){
     // real implementation of getting system resources
  }

  public abstract void print();
}

public class Canon extends Printer{
  public void print(){
    // here you will provide the implementation of print pertaining to Canon
  }
}

public class HP extends Printer{
  public void print(){
    // here you will provide the implementation of print pertaining to HP
  }
}

public class Lexmark extends Printer{
  public void print(){
    // here you will provide the implementation of print pertaining to Lexmark
  }
}

Observe que as classes HP, Canon e Lexmark não fornecem a implementação de getSystemResource().

Por fim, na sua turma principal, você pode fazer o seguinte:

public static void main(String args[]){
  Printer printer = new HP();
  printer.getSystemResource();
  printer.print();
}
26
Oh Chin Boon

Os métodos abstratos meramente definem um contrato que as classes derivadas devem implementam. É assim que você garante que eles sempre o farão.

Então, vamos pegar, por exemplo, uma classe abstrata Shape. Teria um método abstrato draw() que deveria desenhá-lo. (Shape é abstrato, porque não sabemos como desenhar uma forma geral). Ao ter o método abstrato draw em Shape, garantimos que todas as classes derivadas possam realmente ser desenhado, por exemplo Circle implementa draw. Posteriormente, se esquecermos de implementar draw em alguma classe, derivada de Shape, o compilador realmente ajudará a dar um erro.

2
Beginner

Simplesmente, declarando que uma classe é "abstrata", você está aplicando um "contrato" para as classes filho que a herdam, portanto, fornece uma boa maneira de manter o "contrato".

1
Bin Feng

Se tudo que um resumo faz é declarar métodos abstratos, você está correto, é um pouco tolo e uma interface provavelmente seria superior.

Mas muitas vezes uma classe abstrata implementa alguns (talvez até todos) dos métodos, deixando apenas alguns como abstratos. Por exemplo, AbstractTableModel. Isso economiza a reescrita de muito código.

Outra "vantagem" sobre uma interface é que uma classe abstrata pode declarar campos para subclasses usarem. Portanto, se você tiver certeza de que qualquer implementação razoável teria uma String chamada uniqueID, poderá declará-la, além de getters/setters relevantes, na classe abstract, economizando digitação posteriormente.

0
user949300

Classes abstratas são classes que contêm um ou mais métodos abstratos. Um método abstrato é um método declarado, mas não contém implementação. As classes abstratas não podem ser instanciadas e requerem subclasses para fornecer implementações para os métodos abstratos. Vejamos um exemplo de uma classe abstrata e um método abstrato.

Suponha que estivéssemos modelando o comportamento dos animais, criando uma hierarquia de classes que começou com uma classe base chamada Animal. Os animais são capazes de fazer coisas diferentes, como voar, cavar e caminhar, mas existem algumas operações comuns, como comer, dormir e fazer barulho. Algumas operações comuns são realizadas por todos os animais, mas de uma maneira diferente. Quando uma operação é executada de uma maneira diferente, ela é uma boa candidata a um método abstrato (forçando as subclasses a fornecer uma implementação customizada). Vejamos uma classe de base Animal muito primitiva, que define um método abstrato para emitir um som (como um latido de cachorro, um lobo de vaca ou um porco gordo).

public abstract Animal {

public void sleep{
// sleeping time
}
public void eat(food)
{
//eat something
}
public abstract void makeNoise();
}
public Dog extends Animal {
 public void makeNoise() {
 System.out.println("Bark! Bark!");
 }
}
public Cow extends Animal {
 public void makeNoise() {
 System.out.println("Moo! Moo!");
 }
}

Observe que a palavra-chave abstract é usada para denotar um método abstrato e uma classe abstrata. Agora, qualquer animal que queira ser instanciado (como um cachorro ou uma vaca) deve implementar o método makeNoise - caso contrário, é impossível criar uma instância dessa classe. Vejamos uma subclasse Dog and Cow que estende a classe Animal.

Agora você deve estar se perguntando por que não declarar uma classe abstrata como uma interface e fazer com que Dog e Cow implementem a interface. Claro que você poderia - mas também precisaria implementar os métodos de comer e dormir. Usando classes abstratas, você pode herdar a implementação de outros métodos (não abstratos). Você não pode fazer isso com interfaces - uma interface não pode fornecer implementações de métodos.

No Word simples, uma interface deve conter todo o método abstrato, mas nenhuma implementação do método ou não podemos definir um método não abstrato na interface. Na interface, todo o método deve ser abstrato, mas na classe abstrata podemos definir o método abstrato e não abstrato, portanto Para definir o método não abstrato, não precisamos definir outra classe para implementar o comportamento do mesmo objeto. Essa é a vantagem da classe abstrata sobre a interface.

0
Vincent J. Michuki