What is and what is an abstract class for?

29

In object orientation, what is the meaning of an abstract class? What is its purpose?

    
asked by anonymous 17.09.2015 / 15:07

5 answers

35

Abstract classes are classes that basically define a type , I mean, they are just a draft of how classes inheriting from it should behave.

Abstract classes can not be instantiated, as previously mentioned, they are just for other classes to use as a template (inherit their attributes / properties and methods).

They may have abstract or non-abstract methods. Abstract methods can not have body , that is, one must declare only the method signature and they will have to be implemented in the child class (the class that inherits) , methods that are not signed as abstract must have and may be overridden in the child class.

A very simple example of using an abstract class would be (Java example)

abstract class Animal{        
    abstract String getHabitat();

    public String getRaca(){
        return "Raça indefinida";
    }
}

class Cachorro extends Animal{
    public String getHabitat(){
        return "";
    }
}

class Gato extends Animal{
    public String getHabitat(){
        return "indefinido";
    }

    public String getRaca(){
        return "Munchkin";
    }
}

In this case, any class that inherits from Animal must implement the getHabitat() method, otherwise a compile error will occur. As for the getRaca() method, child classes can simply use code that already exists in the abstract class, without bothering to implement it.

So, if you do

Cachorro c = new Cachorro();
System.out.println(c.getRaca()); //A saída será "Raça indefinida"

Gato g = new Gato();
System.out.println(g.getRaca()); //A saída será "Munchkin"
    
17.09.2015 / 15:23
13

The function of an abstract class is to implement partially a type. The best example I know of is the AbstractList class of Java : while the List interface defines a useful but complex type , it does not provide a concrete implementation since there are several ways to implement a list, each with its pros and cons. The ArrayList and LinkedList are two of them. But nothing prevents the programmer from creating his own lists, if necessary.

However, much of what the programmer would have to implement is the same for every list: if you implement a method to add one element to one position, then you have to implement another to add at the end, another to add several, another to add several in a specific position, etc. It's a lot of code to write ... And if in the interface you do not have any concrete implementation (interfaces only to define a type), the abstract class allows part of code (if you do not want / can use it, just overwrite it), and the other part - main - you write yourself.

A simplified example:

// Define um tipo
interface List {
    int size();
    Object get(int indice);
    boolean isEmpty();
    int indexOf(Object o);        
    Iterator iterator();
}

// Implementa parcialmente um tipo
abstract class AbstractList {
    // Esses são os métodos principais, então você é que tem que escrever
    abstract int size();
    abstract Object get(int indice);

    // Esses outros te dão uma "ajuda", fazendo uso do método que você escreveu
    boolean isEmpty() {
        return size() == 0;
    }

    int indexOf(Object o) {
        for ( int i = 0 ; i < size() ; i++ )
            if ( get(i).equals(o) )
                return i;
    }

    Iterator iterator() {
        return new Iterator() {
            int indice = 0;

            boolean hasNext() {
                return indice < size();
            }

            Object next() {
                 return get(indice++);
            }
        };
    }
}

// Implementa um tipo concreto
class ArrayList extends AbstractList {
    Object[] array;

    int size() {
        return array.length;
    }

    Object get(int indice) {
        return array[indice];
    }
}

// Outra implementação
class ListaCom3 extends AbstractList {
    Object obj1;
    Object obj2;
    Object obj3;

    int size() { return 3; }
    Object get(int indice) {
        if ( indice == 0 ) return obj1;
        if ( indice == 1 ) return obj2;
        if ( indice == 2 ) return obj3;
        throw new IllegalArgumentException();
    }
}

Note that the interface (type) requires 5 methods, but with the help of the abstract class each "final" implementation only needs to implement 2.

    
17.09.2015 / 15:45
11

All answers are right. I just want to add a simple information of what the abstract class is.

It is a middle ground between the concrete class and the interface.

It does not have any implementation, that is, it has been (variables) and behavior (methods), including private members, like any other class, but also have public methods without implementation, ie just as contracts, just like it occurs with interfaces.

As with interfaces, these methods, called abstracts, should be implemented in the concrete class that derives from this abstract.

Depending on the situation an abstract class can be used as an interface, since the interface is a purely abstract class (do not fear anything that is not abstract).

To better understand, I suggest some readings:

17.09.2015 / 18:33
6

For better understanding, an abstract class serves as a "model" of inheritance for a concrete class.

As an abstract class can not be instantiated by itself, it is necessary, as stated before, to create a concrete extender class of the abstract class. Thus, methods derived from the abstract class must be overridden in "daughter" classes. However, if an abstract class inherits from another abstract class, it is not necessary to implement abstract methods.

Example:

Abstract class:

abstract class Funcionario {

  protected double salario;

  public double getBonificacao() {
    return this.salario * 1.2;
}

Concrete class:

class Gerente extends Funcionario {

  public double getBonificacao() {
    return this.salario * 1.4 + 1000;
  }
}

References: link

    
17.09.2015 / 15:21
6

Abstract classes serve as a "model" for other classes that inherit from it, and can not be instantiated by itself. To get an object of an abstract class it is necessary to create a more specialized class inheriting from it and then instantiate this new class. The methods of the abstract class should then be overridden in the child classes.

abstract class Conta { 
    private double saldo; 

    public void setSaldo(double saldo) { 
        this.saldo = saldo; 
    } 

    public double getSaldo() { 
        return saldo; 
    } 

    public abstract void imprimeExtrato(); 
}
    
17.09.2015 / 15:21