Interface or Abstract?



  • I read several content on this topic, until I came to this example:

    public interface Funcionario{  
          public void trabalha();  
          public void recebe(double salario);  
    }
    


    public abstract class Geek implements Funcionario{  
        public abstract void trabalha();  
        public abstract void recebe(double salario);  
        public void programa(){  
           System.out.println("import java.io.*; :) ");  
        }  
    }  
    

    public abstract class BusinessMan implements Funcionario{
    public void trabalha(){
    System.out.println("$$$");
    }
    public abstract void recebe(double salario);
    }


    // programador é um geek e também um funcionário...
    public class Programador extends Geek{
    private double salario;
    public void trabalha(){
    super.programa();
    }
    public void recebe(double salario){
    this.salario = salario;
    }
    }

    /* analista também é um geek e um funcionário, mas que trabalha de maneira diferente ao programador*/
    public class Analista extends Geek{
    private double salario;
    public void trabalha(){
    super.programa();
    supervisionaProjeto();
    }
    public void recebe(double salario){
    this.salario = salario;
    }
    private void supervisionaProjeto(){
    System.out.println("Supervisiona");
    }
    }

    public class Gerente extends BusinessMan{
    private double salario;
    private final double BONUS = 1000.0d;
    public void recebe(double salario){
    this.salario = salario + this.BONUS;
    }
    }


    public class Empresa{
    public static void main(String[] args){
    private Funcionario[] funcionario = new Funcionario[5];
    funcionario[0] = new Programador();
    funcionario[1] = new Programador();
    funcionario[2] = new Analista();
    funcionario[3] = new Programador();
    funcionario[4] = new Gerente();
    // faz alguma coisa...
    }
    }

    Source: http://www.guj.com.br/java/6854-classe-abstrata#38794

    I changed interface Funcionario by an abducted class, and I made the other classes, which they once implemented, now extend it. So:

    public abstract class Funcionario {
    public abstract void trabalha();
    public abstract void recebe(double salario);
    }

    public abstract class Geek extends Funcionario{
    @Override
    public abstract void trabalha();

    @Override
    public abstract void recebe(double salario);
    
    public void programa() {
        System.out.println("import java.io.*; :) ");
    }
    

    }

    public abstract class BusinesMan extends Funcionario {

    @Override
    public void trabalha() {
        System.out.println("$$$");
    }
    
    @Override
    public abstract void recebe(double salario);
    

    }

    There was no change in compiling and running.

    My question is:
    In this particular case changes anything with these changes? Do you have any functionality that I will lose or win?

    Note: I am not referring to performance. I am referring to the issue of maintenance or complexity, for example, if later I need to add some sort of employee, will there be a difference in both cases?



  • At first there was not much change. Interfaces are usually preferred when there is no state or implementation, which is your case. And this is the most important thing to watch. This case does not demand classes. If the problem was another I would think differently. Therefore it is important never to go after good practices and analyze the specific problem. Understand what you want. For this it is important to understand the difference between the two.

    You could even have a future limitation using an abstract class because Java only allows "truth" inheritance of only one class. And any class that inherits from the abstract class Funcionario you cannot inherit from another class, you can only implement other interfaces.

    In practice I doubt that this really is a problem in most cases. If you just implement Funcionario in the described classes will allow in the future that you can inherit from some class (abstract or not) since you had only implemented interfaces and no class. But will you modify these existing classes to inherit from another class? It will hurt http://en.wikipedia.org/wiki/Open/closed_principle ? And he's usually important in these cases. I do not say that there is no situation where this can be interesting, but in general it is not.

    Is there any reason to prefer the abstract class? If I don't find one, I'd have the interface. In general the reason is that you need state. Even if you need implementations, I don't know if it would be justifiable, even more in Java 8 with the http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html . Unless you need to implement "implementation details", that is, private methods.

    The way Funcionario is described to me seems to be declaring some characteristics that an element that is an employee of some kind should have. What is different from saying that Funcionario contains important definitions for who are employees. It's the famous difference being and have. Use classes when the derived classes will be that in this case, are employees. Or use interfaces when derived class only they have those characteristics, defined behaviors (but not implemented).

    By name it can be tempting to think Geek or Analista are employees and not only have characteristics of an employee. But the code shows something different. Therefore the correct specification is important to make the correct choice. Maybe you know something we don't know.

    About this can learn more about in https://pt.stackoverflow.com/q/53468/101 (in English, as always, is better) ( https://pt.stackoverflow.com/q/53468/101 ).

    Remember that in thesis it is easier to turn an interface into abstract class if one day this is necessary than the other. In fact, they're both going to work and bring risks.

    Really performance and other technical issues are little important near the engineering problem you will have. In general it is easier to add interfaces. You could have advantages in the abstract class if you want implement or modify existing implementations in it and this is automatically reflected in the descending classes. But this needs to be done so carefully that it is always necessary to question whether it is worth it.




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2