Interface ou Classe ?

Pessoa iniciei meus estudo e recentemente me surgiu um dúvida, no momento em que exercitava o que aprendi.
Se puderem me ajudar agradeço.

Criei um pacote para armazenar minhas classes de veículos e outro pacote para armazenar minhas classes de acessórios opcionais dos veículos.

A dúvida é a seguinte: No pacote acessórios eu teria que criar interfaces para os opcionais, afinal eu terei que implementar vários opcionais no veículos ?

E se eu quiser herdar mais de uma característica de vários outros carros diferente, tornando meu carro uma modelo personalizado contendo peças e acessorios diferentes ?

Eu poderia, criar uma interface acessórios, implementar seus métodos e em seguida fazer um carro herdar esses acessórios.

Qual seria a melhor maneira ???

1 curtida

A melhor maneira sempre depende, não há um único jeito de se fazer as coisas. Mas vamos por partes.

Por que seus acessórios precisam ser interfaces? Não pode ser uma classe normal, ou mesmo abstrata (caso você queira implementar subclasses como AcessorioPainel, AcessorioSeguranca, etc)?

Pensando de forma simples, você teria uma classe Veiculo e uma classe Acessorio. Um veículo poderia ter um conjunto de acessórios (uma lista). Algo assim:

class Acessorio{
  public Acessorio (String nome){...}
}

class Veiculo{
  List<Acessorio> acessorios;   
  public Veiculo(String nome){...}
  public void adicionarAcessorio(Acessorio acessorio) { this.acessorios.add(acessorio); }
}

Se você precisa de algo mais complexo que isso, explique melhor o que deseja fazer.

Abraço.

2 curtidas

Utilizamos interfaces quando queremos “firmar um contrato”.
Por exemplo, vamos supor que temos duas classes:

public class Word {
    public void imprime() {
        //implementação específica para imprimir um arquivo Word
    }
}

e

public class PDF {
    public void imprime() {
        //implementação específica para imprimir um arquivo PDF
    }
}

Não é novidade para ninguém que arquivos em Word e PDF são “imprimiveis”.

Se tivéssemos uma classe utilitária chamada ImpressoraUtil, precisaríamos criar um método que imprime, especificamente, um arquivo em Word e outro método que imprime um arquivo em PDF.
Algo como:

public class ImpressoraUtil() {
    public void imprimeWord(Word arquivo) {
        arquivo.imprime();
    }

    public void imprimePDF(PDF arquivo) {
        arquivo.imprime();
    }
}

Temos que fazer assim pois não podemos garantir que todos as classes que representam arquivos “imprimveis” tem o método imprime().

É exatamente aí que entra a aplicação de Interfaces.
Podemos criar uma Interface chamada de Imprimivel (eu sei que essa palavra não existe, mas é para exemplo).

public interface Imprimivel {
    void imprime();
}

A partir daí, toda classe que desejamos que seja “imprimivel”, podemos apenas implementar a interface pois ao implementá-la, o Java nos obriga a darmos uma implementação ao método void imprime():

public class Word implements Imprimivel {
    public void imprime() {
        //implementação específica para imprimir um arquivo Word
    }
}

e

public class PDF implements Imprimivel {
    public void imprime() {
        //implementação específica para imprimir um arquivo PDF
    }
}

E agora, na nossa classe podemos ter um único método que recebe algo “imprimivel”. Veja:

public class ImpressoraUtil() {
    //repare que o tipo do parâmetro é uma interface, ou seja, esse método recebe um objeto de qualquer classe que implementa a interface Imprimivel
    public void imprime(Imprimivel arquivo) {
        arquivo.imprime(); //pelo contrato da interface, sabemos que TODA classe que implementar a interface Imprimivel terá o método imprime() implementado da sua forma especializada.
    }
}

Depois de tudo isso, minha opinião sobre a sua pergunta: eu costumo utilizar interfaces para “forçar” comportamentos… Não sei se esse é o seu caso.
No seu caso, EU faria uma outra classe chamada Opcional e a classe Veiculo teria uma lista de opcionais.

public class Opcional {
    private String nomeDoOpcional;
    //getters e setters
}

public class Veiculo {
    private List<Opcional> opcionais;
}

Espero ter ajudado.

Abs.

2 curtidas

Existem vários motivos para se criar um interface…como não sabemos seu contexto, não teríamos como afirmar que sim e nem não. Segue algumas dicas para vc estudar e decidir por conta:
Artigo sobre - https://fernandofranzini.wordpress.com/2010/07/07/pizzaria-polimorfica-2/
Aula Gratis - https://fernandofranzini.wordpress.com/2016/10/26/for-j-ead-aula-gratis-interfaces-java/
Curso Completo para vc entender o uso de interfaces - https://for-j.myedools.com/jse-polimorfismo

Cara, eu acho que você devia criar um pacote apenas para as interfaces, isso não vai mudar em nada, apenas vai deixar o seu projeto bem mais organizado.
Quanto aos acessórios você pode criar uma class acessorio sem que a classe carro tenha de herdar acessório.
atenção, quando uma classe herda a outra quer dizer que a subclasse é filho da superclasse, ou seja, por exemplo, uma class cão que herda a class animal, você estaria a dizer que o cão é um animal, assim sendo você não pode dizer que carro é um acessório.

Espero ter ajudado.

Excelente explicação Igor !
Na verdade fiz essa pergunta pra fins de duvidas de estudo mesmo, pois estava meio confuso.

Muito obrigado pelo esclarecimento, me ajudou muito.

1 curtida

Legal!
Fico feliz por ter ajudado!

Se achar certo, poderia marcar minha resposta como solução, por favor?

Obrigado!