Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Projeto] Controle de dispositivos

Ao invés de criar o atributo ligado nas classes Luz e Ar-condicionado, Criei uma classe abstrata chamada Dispositivo com o atributo ligado = false, fiz com que a interface fosse implementada nessa classe abstrata e por fim nas especializações (Luz e Ar-condicionado) apenas fiz com que herdassem o que já havia na classe Dispositivo aplicando a sobrescrita dos métodos ligar() e desligar().

package org.example.ControleDeDispositivos;

public interface IControlavel {
    void ligar();
    void desligar();
}
public abstract class Dispositivo implements IControlavel {
    private boolean ligado = false;

    public boolean isLigado() {
        return ligado;
    }

    public void setLigado(boolean ligado) {
        this.ligado = ligado;
    }
}
public class Luz extends Dispositivo {

    @Override
    public void ligar() {
        if (!isLigado()) {
            setLigado(true);
            System.out.println("Luz Ligada.");
        } else {
            System.out.println("A luz já está ligada.");
        }
    }

    @Override
    public void desligar() {
        if (isLigado()) {
            setLigado(false);
            System.out.println("Luz desligada.");
        } else {
            System.out.println("A luz já está desligada.");
        }
    }
}
public class ArCondicionado extends Dispositivo {

    @Override
    public void ligar() {
        if (!isLigado()) {
            setLigado(true);
            System.out.println("Ar-condicionado ligado.");
        } else {
            System.out.println("O ar-condicionado já está ligado.");
        }
    }

    @Override
    public void desligar() {
        if (isLigado()) {
            setLigado(false);
            System.out.println("Ar-condicionado desligado.");
        } else {
            System.out.println("O ar-condicionado já está desligado.");
        }
    }
}
public class Main {
    public static void main(String[] args) {

        Dispositivo luz = new Luz();
        Dispositivo arCondicionado = new ArCondicionado();

        luz.desligar();
        luz.ligar();
        luz.ligar();
        luz.desligar();
        luz.desligar();

        arCondicionado.desligar();
        arCondicionado.ligar();
        arCondicionado.ligar();
        arCondicionado.desligar();
        arCondicionado.desligar();

    }
}
Console:
A luz já está desligada.
Luz Ligada.
A luz já está ligada.
Luz desligada.
A luz já está desligada.
O ar-condicionado já está desligado.
Ar-condicionado ligado.
O ar-condicionado já está ligado.
Ar-condicionado desligado.
O ar-condicionado já está desligado.
1 resposta
solução!

Olá, Leandro. Como vai?

Excelente solução! Essa é exatamente a essência da Programação Orientada a Objetos (POO). Ao criar a classe abstrata Dispositivo para concentrar o estado comum (ligado) e implementar a interface IControlavel, você eliminou com sucesso a duplicação de código (DRY - Don't Repeat Yourself).

O design do seu código ficou muito elegante: a interface dita o comportamento esperado, a classe abstrata fornece a base estrutural e os atributos, e as classes filhas (Luz e ArCondicionado) cuidam apenas das especializações e das mensagens específicas de cada contexto.

Aproveitando o gancho da sua excelente estrutura, dá para elevar o nível desse projeto eliminando mais uma repetição imperceptível. Note que a lógica do if/else dentro do método ligar() e desligar() é idêntica nas duas classes; a única coisa que muda é a palavra impressa no console ("Luz" ou "Ar-condicionado").

Uma boa prática avançada em Java para cenários como o seu é aplicar o padrão Template Method ou simplesmente subir a lógica de validação para a classe abstrata, deixando as filhas responsáveis apenas por dizer seus "nomes".

Veja como seu código poderia ser refatorado para reduzir ainda mais as linhas repetidas:

1. Ajuste na Classe Abstrata Dispositivo

Podemos criar um método abstrato chamado getNomeDispositivo() e implementar a lógica do ligar e desligar diretamente na classe pai:

public abstract class Dispositivo implements IControlavel {
    private boolean ligado = false;

    // Cada classe filha será obrigada a fornecer seu próprio nome (ex: "Luz")
    protected abstract String getNomeDispositivo();

    public boolean isLigado() {
        return ligado;
    }

    @Override
    public void ligar() {
        if (!ligado) {
            ligado = true;
            System.out.println(getNomeDispositivo() + " ligado(a).");
        } else {
            System.out.println("O(A) " + getNomeDispositivo() + " já está ligado(a).");
        }
    }

    @Override
    public void desligar() {
        if (ligado) {
            ligado = false;
            System.out.println(getNomeDispositivo() + " desligado(a).");
        } else {
            System.out.println("O(A) " + getNomeDispositivo() + " já está desligado(a).");
        }
    }
}

2. Como ficaria a classe Luz

Ela se torna extremamente enxuta, pois herda toda a lógica de controle e se preocupa apenas com a sua identidade:

public class Luz extends Dispositivo {
    @Override
    protected String getNomeDispositivo() {
        return "Luz";
    }
}

Essa abordagem faz com que, caso amanhã você precise alterar a lógica de ligar/desligar (por exemplo, para lançar uma exceção ou salvar um histórico de logs), você altere em um único lugar (na classe Dispositivo) e todos os aparelhos do sistema herdem a correção automaticamente.

Parabéns pelo excelente entendimento de polimorfismo e herança! Seu código está muito bem escrito e estruturado.

Espero que possa ter lhe ajudado!