Dúvida sobre herançca

25 respostas
M

Estou fazendo o trabalho final de programação e me surgiu uma dúvida, nessa parte do enunciado:

Um computador suporta dois tipos de portas de comunicação: paralela e USB. Nessas portas podem se
conectar dispositivos de armazenamento, ou seja, unidades que contém arquivos.

Cada uma dessas portas suporta tipos diferentes de dispositivos, mas tem métodos comuns como adicionaDisp(); e removeDisp();. Então criei uma classe Porta que é superclasse das classes de porta paralela e usb. Só que na hora de usá-la me surgiu uma dúvida: Eu uso uma coleção da classe Porta ou duas coleções(uma para cada tipo de porta)? Acho que a primeira seria o ideal, mas não sei como fazer daí =S

25 Respostas

B

Não seria uma coleção de dispositivos? Dentro de cada dispositivo é que teria um atributo porta falando qual ele suporta.

M

Obrigado pela atenção Bruno Laturner.

Eu sou novato ainda, mas isso me parece errado… Afinal um computador tem portas e não dispositivos, certo?
Outra coisa que não me deixa fazer isso é que eu tenho que dizer quantas portas paralelas e quantas portas usb o computador terá assim que é iniciado.

abelgomes

ai depende de como esta instanciando os osbjeto…

assim?

Porta usb = new Usb(); Porta serial = new Serial();
ou

Usb usb = new Usb();

se for no primeiro caso vc pode fazer uma colecao só… se nao tem que ser duas coleçoes…

M

abelgomes:
ai depende de como esta instanciando os osbjeto…

assim?

Porta usb = new Usb(); Porta serial = new Serial();
ou

Usb usb = new Usb();

se for no primeiro caso vc pode fazer uma colecao só… se nao tem que ser duas coleçoes…

Eu não comecei ainda, estou só pensando em como fazer. Mas o problema que encontro no primeiro modelo é assim:

Digamos que eu tenha o seguinte código:

portas.addAll(portasUSB); portas.addAll(portasParalelas);

Certo, agora eu tenho todas as portas dentro de uma coleção. Digamos que eu tenha adicionado 2 USB e 1 Paralela. Como eu faço para não deixar o usuário utilizar as 3 portas como USB/Paralelo?

thegoergen

Acho que daí na hora de pegar a porta usada tu verifica o tipo…

B

Eu faria com duas coleções mesmo.

M

E essas duas coleções continuariam herdando de porta né?

thegoergen

É.

A herança da porta tem que deixar. Porque existem métodos comuns aos 2 tipos de porta, com certeza.

luistiagos

acho que neste seu caso não necessita usar herança… pense no seguinte o que uma porta usb tem de diferente a uma porta serial? ambas são para transmição de dados correto? ou seja tem a mesma finalidade… porem tem particularidades como o seu conector por exemplo…
qual seria o nivel de detalhamento das portas nesta sua app? usaria uma tal forma de detalhamento por exemplo uma determinada caracteristica que uma porta tem e a outra não teria… ou alguma funcionalidade exclusiva de X tipo de porta que Y e Z seriam diferents… sendo assim justifica-se vc ultilizar herança porem se as funcionalidades e os atributos destas diferentes portas são o mesmos… se o que muda é o tipo de conector velocidade, etc… onde todas tem um tipo de conector, todas tem uma velociade X, todas tem atributos e funcionalidades iguais porem o que muda são os valores destes atributos (Ex: a velociade, o tipo de conector, etc…) então vc não precisa usar herança.
Para estes casos use uma classe Porta com seus devidos atributos e funcionalidades e com um atributo tipo da porta no qual vc indicara se éla é USB, Serial, LPT1, etc…

tnaires
Olá Márcio, O código dos métodos addDisp e removeDisp varia para cada tipo de porta? Caso positivo, uma sugestão alternativa seria fazer de Porta uma interface:
public interface Porta {
    // Um nome mais sugestivo do que addDisp
    void conectar(Dispositivo d);
    // Um nome mais sugestivo do que removeDisp
    Dispositivo desconectar();
}

public PortaUSB implements Porta {
    public void conectar(Dispositivo d) {
        // Código para conectar na porta USB
    }

    public Dispositivo desconectar() {
        // Retorna o dispositivo USB desconectado
    }
}

public PortaParalela implements Porta {
    public void conectar(Dispositivo d) {
        // Código para conectar na porta Paralela
    }

    public Dispositivo desconectar() {
        // Retorna o dispositivo desconectado
    }
}
Assim, você mantém uma única coleção de portas, e passa os detalhes de cada porta para as implementações da interface Porta. Abraços
tnaires

A sugestão do luistiagos é bastante interessante. Os tipos das portas poderiam ser implementados com enums.

M

A diferença é basicamente o que você pode conectar em cada porta.

Para as portas paralelas existem os dispositivos de Hard Disk (HD), CD e DVD. Para as portas USB existem o HD Externo e Pen Drive. Nos HDs e Pen Drives podem-se armazenar dados diretamente na
unidade. Nos dispositivos de CD e DVD é necessário inserir uma mídia compatível com o dispositivo. As
mídias CD e DVD são lidas na unidade de DVD, porém, a unidade de CD consegue ler somente a mídia
CD.

Pelo que vejo, as portas seriam identicas em tudo, menos no que suportam. Ou talvez herança não seja o melhor meio de resolver isso? Estou vendo agora que se implementar isso com herança terei problemas em fazer o CD e DVD não armazenarem arquivos =/

tnaires

Você poderia postar o enunciado completo do exercício?

B

Eu considero a herança(o extends do Java em específico) como endeusada demais. Tem que pensar 10 vezes antes de usar ela.

M

Enunciado:

CENÁRIO

Um computador suporta dois tipos de portas de comunicação: paralela e USB. Nessas portas podem se
conectar dispositivos de armazenamento, ou seja, unidades que contém arquivos. O computador pode ter
uma quantidade qualquer dos dois tipos de portas. Mas uma porta pode estar ligada a somente um
dispositivo de armazenamento.

Para as portas paralelas existem os dispositivos de Hard Disk (HD), CD e DVD. Para as portas USB
existem o HD Externo e Pen Drive. Nos HDs e Pen Drives podem-se armazenar dados diretamente na
unidade. Nos dispositivos de CD e DVD é necessário inserir uma mídia compatível com o dispositivo. As
mídias CD e DVD são lidas na unidade de DVD, porém, a unidade de CD consegue ler somente a mídia
CD.

Podem ser colocados pastas e arquivos nos HDs, Pen Drive, e nas mídias de CD e DVD. Porém, eles têm
um limite de capacidade, ou seja, a soma do tamanho dos arquivos não pode exceder a capacidade do
dispositivo. Cada arquivo tem seu próprio tamanho, mas ocupa na unidade o seu tamanho mais a
quantidade de caracteres do seu nome. A definição de uma pasta ocupa 8 bytes mais a quantidade de
caracteres do seu nome.

Quando um dispositivo é conectado a um computador, ele ganha uma letra representando a sua unidade.
Pode ser solicitado ao computador para exibir todas as unidades. Também pode ser solicitado o conteúdo
(pastas e arquivos) para uma unidade.

DESCRIÇÃO

Crie uma aplicação de interface gráfica que represente esse computador. Ao criar um computador, precisa
especificar quais e quantos os tipos de portas. A aplicação precisa apresentar todas as unidades e seus
conteúdos.

A partir da aplicação, podem se criar dispositivos e mídias. Pode-se conectar e desconectar dispositivos, e
inserir as mídias em seus respectivos dispositivos.

A aplicação precisa permitir que se criem pastas e arquivos nas unidades. Não é necessário alterar e nem
excluir esses conteúdos.

maior_abandonado

não que eu va ajudar muito no tópico, no assunto relativo mesmo, mais parei de ler no seu enunciado…

de onde vc tirou essa citação??? que eu saiba, os tipos são paralela e serial, usb é um tipo que possue caracteristicas de ambas…

ao menos uma coisa que diminui a chance de vc perder nota… confirma isso ai :wink:

M

maior_abandonado:
não que eu va ajudar muito no tópico, no assunto relativo mesmo, mais parei de ler no seu enunciado…

de onde vc tirou essa citação??? que eu saiba, os tipos são paralela e serial, usb é um tipo que possue caracteristicas de ambas…

ao menos uma coisa que diminui a chance de vc perder nota… confirma isso ai ;)

O enunciado é o oficial do professor. Provavelmente ele se enganou na hora de fazer hehe.

B

Interpretação faz parte do exercício.

Ele não fala que “computadores” possuem portas paralelas e usb. O exercício fala de um único computador em específico que tem portas paralela e USB. (Serial é antigão, ninguém mais vende :wink:

maior_abandonado
Bruno Laturner:
maior_abandonado:
de onde vc tirou essa citação??? que eu saiba, os tipos são paralela e serial, usb é um tipo que possue caracteristicas de ambas...

Interpretação faz parte do exercício.

Ele não fala que "computadores" possuem portas paralelas e usb. O exercício fala de um único computador em específico que tem portas paralela e USB. (Serial é antigão, ninguém mais vende ;)

ta...a intenção era ajudar mesmo...achei que vc fosse entregar isso...

bom...de qualquer jeito eu vo tenta da meus 5 cents ao criador do tópico...

bom...somando ao que o tnaires falou, vc poderia cria uma classe computador...eu dexei um exemplo que eu acredito ser correto ai embaixo

marcio_gs:
Certo, agora eu tenho todas as portas dentro de uma coleção. Digamos que eu tenha adicionado 2 USB e 1 Paralela. Como eu faço para não deixar o usuário utilizar as 3 portas como USB/Paralelo?

bom, se a sua duvida seria como verificar se o item adicionado no seu array, no seu list, ou seja la o q for é uma porta do tipo especifico, vc pode usar o operador instanceOf, para verificar se o objeto em questão é do tipo portaUSB ou do tipo portaParalela... veja o loop que eu fiz...

para não adicionar um dispositivo de tipo errado, vc pode coloca um metodo getTypePort no dispositivo, retornando porta paralela ou usb, ou o q for, uma string escrito o tipo por exemplo, e verificar isso no metodo conecta, se for do tipo diferente do da porta em que se tenta conectar, lance uma illegalArgumentException

veja o código abaixo:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package testes;


//código do cara ali atras

import java.util.ArrayList;
/**
 *
 * @author flavio
 */
class Computador {
    private final ArrayList<Porta> portas;

    public Computador (ArrayList portas){
        this.portas = portas;
    }

    public Porta getPort(int index){
        return portas.get(index);
    }

}
public class User{
    public static void main(String args[]){

        ArrayList<Porta> portas = new ArrayList<Porta>();

        portas.add(new PortaUSB());
        portas.add(new PortaParalela());
        portas.add(new PortaUSB());
        portas.add(new PortaParalela());
        portas.add(new PortaUSB());
        portas.add(new PortaParalela());
        portas.add(new PortaUSB());

        Computador c = new Computador(portas);

        
        for (int i=0;i<portas.size();i++){

            if (c.getPort(i) instanceof PortaUSB ){
                System.out.println("usb");
            }else if (c.getPort(i) instanceof PortaParalela){
                System.out.println("paralela");
            }else
                System.out.println("porta desconhecida");
        }

        //agora vamos conectar um dispositivo na porta correta e um não pra testar
        try{
            portas.get(0).conectar(new Dispositivo("USB"));
            System.out.println("chego aqui sem erros");
            portas.get(0).conectar(new Dispositivo("paralela"));
        }catch(IllegalArgumentException ile){
            System.out.println("caiu aqui");
            ile.printStackTrace();
        }

    }


}

//código do tnaires, com algumas poucas modificações que eu aconselharia
interface Porta {
    // Um nome mais sugestivo do que addDisp
    boolean conectar(Dispositivo d);
    // Um nome mais sugestivo do que removeDisp
    boolean desconectar();
}

class PortaUSB implements Porta {
    public boolean conectar(Dispositivo d) {
        // Código para conectar na porta USB
        if (d.getType().equals("USB")){
            //código que conecta
            return true;
        }else{
            throw new IllegalArgumentException("dispositivo não permitido nessa porta");
        }

    }

    public boolean desconectar() {
        //esse jeito da esxceção poderia ser usado no conectar, bem como odo conectar aqui
        //a seu criterio
        try{
            //tenta desconectar
            return true;
        }catch(Exception e){//crie uma exception e coloque aqui
            return false;
        }
        
    }
}

class PortaParalela implements Porta {
    public boolean conectar(Dispositivo d) {
        // idem a usb
        return true;
    }

    public boolean desconectar() {
        // idem a usb
        return true;
    }
}

class Dispositivo{
    private String type;
    public Dispositivo(String type){
        this.type = type;
    }
    public String getType(){
        return type;
    }
}

>

M

Muito obrigado pela ajuda maior_abandonado. Só tem um problema. Não podemos usar instanceof, pois segundo o professor vai contra a Orientaçao a Objetos. Como não aprendemos interface em sala de aula ainda, não sei se podemos usar. Vou perguntar pra ele na próxima aula.

luistiagos

Isto é desnecessario como ja disse anteriormente…

vc pode fazer um esquema mais ou menos assim:

class Porta {

    private String tipo;

     public boolean conectar(Dispositivo d) {   
        // Código para conectar na porta USB   
        if (d.getType().equals(this.tipo)){   
            //código que conecta   
            return true;   
        }else{   
            throw new IllegalArgumentException("dispositivo não permitido nessa porta");   
        }   

     public void desconectar() {
       ....
     }

 }

Porta não precisa ser uma superclasse que tera subclasses de tipos de porta…
pode ser uma unica classe que tera um tipo para definir qual tipo sera… se o que diferencia uma porta da outra é apenas o tipo e não a logica de implementação não a o pq ter uma hierarquia para ela…

M

Obrigado pela ajuda luistiagos, vamos ver se eu consigo resolver com sua dica.

tnaires
luistiagos:
class Porta {

    private String tipo;

     public boolean conectar(Dispositivo d) {   
        // Código para conectar na porta USB   
        if (d.getType().equals(this.tipo)){   
            //código que conecta   
            return true;   
        }else{   
            throw new IllegalArgumentException("dispositivo não permitido nessa porta");   
        }   

     public void desconectar() {
       ....
     }

 }
Evoluindo a idéia:
// Substituindo as strings pelos enums.
public enum Tipo {
    USB, PARALELO;
}

public class Porta {
    private Tipo tipo;
    // Uma porta pode conectar apenas um dispositivo, como diz o enunciado.
    private Dispositivo dispositivo;

    public Porta(Tipo t) {
        this.tipo = tipo;
    }

    // Se o método dispara uma exceção, retornar um booleano é desnecessário.
    public void conectar(Dispositivo d) {
        if (this.tipo != d.getTipo()) {
            throw new IllegalArgumentException("Dispositivo não permitido nesta porta.");
        }

        this.dispositivo = d;
    }

    public Dispositivo desconectar() {
        Dispositivo result = this.dispositivo;
        this.dispositivo = null;
        return dispositivo;
    }
}
B
Várias maneiras de resolver o mesmo problema.
package computador;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Computador
{
   Portas portasUSB;
   Portas portasParalelo;

   Portas paralelo()
   {
      return portasParalelo;
   }

   Portas USB()
   {
      return portasUSB;
   }

   public static void main(String[] args)
   {
      Computador pc = Computador.montarComputador();

      Dispositivo p1 = new DispositivoParalelo();

      pc.paralelo().conectar(p1);
      pc.paralelo().desconectar(new DispositivoParalelo());
      pc.paralelo().desconectar(p1);
      pc.paralelo().conectar(new DispositivoParalelo());

      Dispositivo usb1 = new DispositivoUSB();
      Dispositivo usb2 = new DispositivoUSB();
      Dispositivo usb3 = new DispositivoUSB();

      pc.USB().conectar(usb1);
      pc.USB().conectar(usb2);
      pc.USB().conectar(usb3);

      try
      {
         pc.USB().conectar(new DispositivoParalelo());
      }
      catch (IllegalArgumentException e)
      {
         System.out.println(e.getMessage());
      }
   }

   public Computador(int nUSB, int nParalela)
   {
      portasUSB = new PortasUSB(nUSB);
      portasParalelo = new PortasParalelo(nParalela);
   }

   public static Computador montarComputador()
   {
      Scanner in = new Scanner(System.in);

      System.out.println("Quantas portas USBs?");
      int nUSB = Integer.parseInt(in.nextLine());

      System.out.println("Quantas portas Paralelas?");
      int nParalela = Integer.parseInt(in.nextLine());

      return new Computador(nUSB, nParalela);
   }
}

class Portas
{
   final int CAPACIDADE;
   final List<Dispositivo> portas;
   final TipoPorta tipo;

   protected Portas(int capacidade, TipoPorta tipo)
   {
      this.CAPACIDADE = capacidade;
      this.portas = new ArrayList<Dispositivo>(CAPACIDADE);
      this.tipo = tipo;
   }

   public boolean conectar(Dispositivo d)
   {
      if (!this.tipo.equals(d.getTipo()))
         throw new IllegalArgumentException("Tipo de porta inexperado. Esperado " + this.tipo + ", encontrado " + d);

      if (portas.size() < CAPACIDADE)
      {
         System.out.println(d + " conectado");
         return portas.add(d);
      }
      System.out.println("Não pode conectar " + d + ": Portas insuficientes.");
      return false;
   }

   public boolean desconectar(Dispositivo d)
   {
      boolean b;
      if (b = portas.remove(d))
         System.out.println(d + " desconectado");
      else
         System.out.println("Não pode desconectar " + d + ": Dispositivo não encontrado");

      return b;
   }
}

class PortasUSB extends Portas
{
   public PortasUSB(int capacidade)
   {
      super(capacidade, TipoPorta.USB);
   }
}

class PortasParalelo extends Portas
{
   public PortasParalelo(int capacidade)
   {
      super(capacidade, TipoPorta.PARALELO);
   }
}

abstract class Dispositivo
{
   protected TipoPorta tipo = null;

   protected Dispositivo()
   {
   }

   public TipoPorta getTipo()
   {
      return tipo;
   }

   @Override
   public String toString()
   {
      return "Dispositivo " + tipo + " " + hashCode();
   }
}

class DispositivoUSB extends Dispositivo
{
   public DispositivoUSB()
   {
      tipo = TipoPorta.USB;
   }
}

class DispositivoParalelo extends Dispositivo
{
   public DispositivoParalelo()
   {
      tipo = TipoPorta.PARALELO;
   }
}

enum TipoPorta
{
   USB, PARALELO
};
M

Muito obrigado mesmo pessoal, nem sei como agradecer a ajuda.

Criado 26 de novembro de 2008
Ultima resposta 27 de nov. de 2008
Respostas 25
Participantes 7