Uma clinica médica deseja um sistema de informação para gerenciar suas atividades. A clínica possui diversos médicos associados que atendem a diversas especialidades (ex., clínico geral, cardiologista, dermatologista, neurologista etc). De um médico deseja-se saber nome, número no Conselho Regional de Medicina (CRM), endereço, telefone, horários de atendimento (hora início e hora fim) em cada dia da semana, especialidades que ele atende e planos de saúde aos quais está conveniado. De uma especialidade deseja-se saber o nome e o código do CRM. De um plano de saúde deseja-se saber razão social, CNPJ, endereço e telefone.
Pacientes marcam consultas com médicos. Na marcação de uma consulta, deve-se informar o paciente, o médico, a data e a hora da consulta e o plano de saúde, caso a consulta não seja particular.
Caso o paciente não seja ainda cadastrado, deve informar nome, telefone, data de nascimento, endereço e profissão.
Durante uma consulta, o médico pode registrar três tipos de observações: textos a respeito das queixas do paciente, textos sobre as prescrições de medicamentos e exames solicitados e textos sobre resultados dos exames e respostas ao tratamento efetuado. Além disso, o médico pode consultar outras observações que ele mesmo tenha feito em consultas anteriores do paciente.
Crie uma classe para teste, contendo um método main. Dentro dele, crie médicos, pacientes e consultas.
- *Use herança(Pessoa, medico, medico/especialidade(ex.: cardiologista), paciente) e encapsulamento
*Use construtores sobrecarregados
*Sobrescreva métodos na subclasse da superclasse|
Pacientes marcam consultas com médicos. Na marcação de uma consulta, deve-se informar o paciente, o médico, a data e a hora da consulta e o plano de saúde, caso a consulta não seja particular.
Caso o paciente não seja ainda cadastrado, deve informar nome, telefone, data de nascimento, endereço e profissão.
Durante uma consulta, o médico pode registrar três tipos de observações: textos a respeito das queixas do paciente, textos sobre as prescrições de medicamentos e exames solicitados e textos sobre resultados dos exames e respostas ao tratamento efetuado. Além disso, o médico pode consultar outras observações que ele mesmo tenha feito em consultas anteriores do paciente.
- *Use herança(Pessoa, medico, medico/especialidade(ex.: cardiologista), paciente) e encapsulamento
*Use construtores sobrecarregados
*Sobrescreva métodos na subclasse da superclasse|
Passo 1
O que o enunciado pede (em termos claros) e as informações fornecidas:
- Criar um sistema simples (modelo orientado a objetos) para uma clínica médica.
- Informações exigidas:
- Médico: nome, CRM, endereço, telefone, horários de atendimento (hora início e fim para cada dia da semana), especialidades, planos de saúde conveniados.
- Especialidade: nome e código do CRM.
- Plano de saúde: razão social, CNPJ, endereço, telefone.
- Paciente: nome, telefone, data de nascimento, endereço, profissão (se ainda não cadastrado).
- Consulta: paciente, médico, data e hora, plano de saúde (opcional, caso não seja particular).
- Observações registradas durante consulta: textos sobre queixas, prescrições/exames solicitados, resultados/respostas ao tratamento — e o médico pode consultar observações antigas que ele mesmo tenha feito para o mesmo paciente.
- Requisitos de implementação:
- Usar herança: pelo menos as classes Pessoa → Médico, Paciente (e especialidades como classes separadas conforme necessário).
- Encapsulamento (atributos privados + getters/setters).
- Construtores sobrecarregados.
- Sobrescrever métodos em subclasses (por exemplo, toString).
- Além disso: criar uma classe de teste com método main que cria médicos, pacientes e consultas (e demonstra o uso).
Passo 2
Escolha de design (como vamos organizar as classes)
- Criar uma superclasse abstrata Pessoa com os atributos comuns (nome, endereço, telefone) e métodos básicos.
- Criar subclasses Medico e Paciente que estendem Pessoa. Cada uma terá atributos específicos.
- Criar classes de apoio: Especialidade, PlanoSaude, Horario (para representar início/fim), Consulta, Observacao e um enum ObservacaoTipo.
- Manter os atributos privados (encapsulamento). Fornecer getters e setters públicos quando necessário.
- Usar construtores sobrecarregados para permitir criação com diferentes níveis de informação (por exemplo, Pessoa com apenas nome e telefone; Paciente com todos os dados).
- Sobrescrever o método toString() nas subclasses para facilitar debugging/saída legível (isso cumpre o requisito “sobrescrever métodos na subclasse”).
Passo 3
Explicando detalhes importantes (encapsulamento e herança) — o que implementar e por quê
- Encapsulamento: atributos privados evitam acesso direto. Em prova, escreva “private String nome;” e crie “public String getNome()” e “public void setNome(String nome)”. Isso protege o estado interno.
- Herança: declarar “abstract class Pessoa” e depois “class Medico extends Pessoa”. Assim reutilizamos nome, endereço e telefone sem repetir código.
- Construtores sobrecarregados: implementar mais de um construtor para cada classe. Exemplo em Paciente:
- Paciente(String nome, String telefone)
- Paciente(String nome, String telefone, LocalDate dataNascimento, String endereco, String profissao)
Na prova, diga que sobrecarregou para facilitar testes e criação de objetos com dados parciais.
- Sobrescrita (override): em cada subclasse fazer “@Override public String toString()” para mostrar informações relevantes. Em Java você escreve @Override acima do método para indicar a sobrescrita.
Passo 4
Como representar horários e dias da semana (detalhe prático)
- Usar o enum DayOfWeek (de java.time) para mapear dias da semana.
- Representar horário de atendimento com uma classe Horario contendo LocalTime inicio e LocalTime fim.
- No médico, usar um Map<DayOfWeek, Horario> para armazenar o horário de cada dia.
- Implementar métodos auxiliares como “adicionarHorario(DayOfWeek dia, Horario h)” e “isDisponivelEm(LocalDateTime dt)” que checa se o horário pedido está dentro do Horario do dia correspondente.
Passo 5
Como registrar observações durante uma consulta
- Criar enum ObservacaoTipo com valores QUEIXA, PRESCRICAO, RESULTADO.
- Cada Observacao tem tipo, texto e timestamp (LocalDateTime).
- Consulta contém uma lista de Observacao. Permitir adicionar observações durante/apos a consulta.
- O médico pode consultar observações anteriores que ELE mesmo fez para um paciente: implementar em Medico um método que recebe Paciente e retorna as Observacoes de consultas anteriores daquele paciente cujo autor é o próprio médico (comparando por referência ou por CRM).
Passo 6
Estruturar a classe Consulta
- A Consulta guarda: Paciente paciente, Medico medico, LocalDateTime dataHora, PlanoSaude plano (nullable se particular), List<Observacao> observacoes.
- Métodos úteis:
- adicionarObservacao(Observacao obs)
- listarObservacoes()
- obterObservacoesPorTipo(ObservacaoTipo tipo)
- Também é bom manter em Paciente uma lista de consultas para histórico (lista atualizada quando marcamos uma consulta).
Passo 7
Exemplo prático de uso (o que colocaremos no main)
- Criar instâncias de Especialidade, PlanoSaude.
- Criar Medico com horários, especialidades e convênios.
- Criar Paciente (com construtor simples e completo para mostrar sobrecarga).
- Criar Consulta ligando Paciente e Médico, com ou sem PlanoSaude.
- Adicionar observações à consulta (dos três tipos).
- Demonstrar o médico consultando observações anteriores feitas por ele para o paciente.
- Imprimir informações para mostrar que tudo está funcionando.
Passo 8
Dicas rápidas para a prova (o que escrever e o que não esquecer)
- Desenhe um pequeno diagrama UML: Pessoa ← Medico, Paciente; acompanhe com Especialidade e PlanoSaude ligados a Medico; Consulta liga Medico–Paciente.
- Liste atributos principais em cada classe e métodos públicos principais (get/set, construtores, adicionarObservacao, marcarConsulta).
- Declare visibilidade dos atributos (private) e anote “getters/setters” — isso demonstra encapsulamento.
- Mostre pelo menos um método sobrescrito (toString) e um construtor sobrecarregado para cada subclasse.
- Se pedirem código, entregue classes coesas e com nomes claros; faça o main demonstrando criação de objetos e algumas operações.
Resposta
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
/**
* Exemplo completo num único ficheiro para demonstrar:
* - Herança (Pessoa -> Medico, Paciente)
* - Encapsulamento (atributos privados + getters/setters)
* - Construtores sobrecarregados
* - Sobrescrita de métodos (toString)
*
* Classe de teste: Teste com método main cria médicos, pacientes e consultas.
*/
public class Teste {
public static void main(String[] args) {
// Criando especialidades
Especialidade cardiologia = new Especialidade("Cardiologia", "CRM-CARD-01");
Especialidade dermatologia = new Especialidade("Dermatologia", "CRM-DERM-02");
// Criando planos de saúde
PlanoSaude planoA = new PlanoSaude("VidaBem S/A", "12.345.678/0001-90", "Av. Central, 100", "11-4000-0000");
PlanoSaude planoB = new PlanoSaude("SaudeFácil Ltda", "98.765.432/0001-11", "R. Saúde, 50", "11-5000-1111");
// Criando médico com construtor completo
Medico drFulano = new Medico("Dr. Fulano", "Rua das Flores, 10", "11-9999-0000", "CRM12345");
drFulano.addEspecialidade(cardiologia);
drFulano.addEspecialidade(dermatologia);
drFulano.addConvenio(planoA);
// Adicionando horários (segunda a sexta das 09:00 às 17:00)
Horario horarioDia = new Horario(LocalTime.of(9, 0), LocalTime.of(17, 0));
drFulano.addHorario(DayOfWeek.MONDAY, horarioDia);
drFulano.addHorario(DayOfWeek.TUESDAY, horarioDia);
drFulano.addHorario(DayOfWeek.WEDNESDAY, horarioDia);
drFulano.addHorario(DayOfWeek.THURSDAY, horarioDia);
drFulano.addHorario(DayOfWeek.FRIDAY, horarioDia);
// Criando outro médico (sobrecarregando construtor)
Medico draSicrana = new Medico("Dra. Sicrana", "Av. Saúde, 200", "11-9888-7777", "CRM54321");
draSicrana.addEspecialidade(dermatologia);
draSicrana.addConvenio(planoB);
Horario periodoTarde = new Horario(LocalTime.of(13, 0), LocalTime.of(18, 0));
draSicrana.addHorario(DayOfWeek.MONDAY, periodoTarde);
draSicrana.addHorario(DayOfWeek.WEDNESDAY, periodoTarde);
// Criando paciente com construtor simples (apenas nome e telefone)
Paciente pacienteJoao = new Paciente("João Silva", "11-7777-6666");
// Atualizando dados usando setters (simula cadastro posterior)
pacienteJoao.setEndereco("R. dos Estudantes, 123");
pacienteJoao.setDataNascimento(LocalDate.of(1985, 4, 20));
pacienteJoao.setProfissao("Engenheiro");
// Criando paciente com construtor completo
Paciente pacienteMaria = new Paciente("Maria Oliveira", "11-6666-5555", LocalDate.of(1990, 8, 15), "R. Primavera, 45", "Professora");
// Marcando consultas
LocalDateTime dataHoraConsulta1 = LocalDateTime.of(2025, 10, 15, 10, 0); // 15/10/2025 10:00
Consulta consulta1 = new Consulta(pacienteJoao, drFulano, dataHoraConsulta1, planoA); // com plano
pacienteJoao.adicionarConsulta(consulta1);
LocalDateTime dataHoraConsulta2 = LocalDateTime.of(2025, 10, 16, 14, 30);
Consulta consulta2 = new Consulta(pacienteMaria, draSicrana, dataHoraConsulta2, null); // particular
pacienteMaria.adicionarConsulta(consulta2);
// Durante a consulta, médico registra observações
consulta1.adicionarObservacao(new Observacao(ObservacaoTipo.QUEIXA, "Paciente refere dor no peito há 2 dias."));
consulta1.adicionarObservacao(new Observacao(ObservacaoTipo.PRESCRICAO, "Solicitar ECG e prescrever AAS 100mg diário."));
consulta1.adicionarObservacao(new Observacao(ObservacaoTipo.RESULTADO, "ECG com sinais de isquemia (a confirmar)."));
consulta2.adicionarObservacao(new Observacao(ObservacaoTipo.QUEIXA, "Erupção cutânea no braço esquerdo."));
consulta2.adicionarObservacao(new Observacao(ObservacaoTipo.PRESCRICAO, "Prescrever pomada anti-inflamatória e evitar exposição."));
consulta2.adicionarObservacao(new Observacao(ObservacaoTipo.RESULTADO, "Melhora após 7 dias."));
// Imprimindo dados para demonstração
System.out.println("=== Médicos ===");
System.out.println(drFulano);
System.out.println(draSicrana);
System.out.println("\n=== Pacientes ===");
System.out.println(pacienteJoao);
System.out.println(pacienteMaria);
System.out.println("\n=== Consulta 1 (João com Dr. Fulano) ===");
System.out.println(consulta1);
System.out.println("Observações da consulta 1:");
consulta1.listarObservacoes().forEach(System.out::println);
System.out.println("\n=== Consulta 2 (Maria com Dra. Sicrana) ===");
System.out.println(consulta2);
consulta2.listarObservacoes().forEach(System.out::println);
// Médico consulta observações anteriores que ele mesmo fez para o paciente
System.out.println("\n=== Observações anteriores do Dr. Fulano para João ===");
List<Observacao> historicoFulanoJoao = drFulano.consultarObservacoesAnteriores(pacienteJoao);
historicoFulanoJoao.forEach(System.out::println);
// Verificar disponibilidade de médico para um horário
LocalDateTime tentativa = LocalDateTime.of(2025, 10, 15, 11, 0); // quarta-feira 11:00
System.out.println("\nDr. Fulano disponível em " + tentativa + "? " + drFulano.isDisponivelEm(tentativa));
}
// --- CLASSES DO MODELO ---
// Superclasse abstrata Pessoa (encapsulamento: atributos privados)
static abstract class Pessoa {
private String nome;
private String endereco;
private String telefone;
public Pessoa(String nome) {
this(nome, null, null);
}
public Pessoa(String nome, String endereco, String telefone) {
this.nome = nome;
this.endereco = endereco;
this.telefone = telefone;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getEndereco() {
return endereco;
}
public void setEndereco(String endereco) {
this.endereco = endereco;
}
public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
@Override
public String toString() {
return "Pessoa{nome='" + nome + "', endereco='" + endereco + "', telefone='" + telefone + "'}";
}
}
// Especialidade
static class Especialidade {
private String nome;
private String codigoCRM;
public Especialidade(String nome, String codigoCRM) {
this.nome = nome;
this.codigoCRM = codigoCRM;
}
public String getNome() {
return nome;
}
public String getCodigoCRM() {
return codigoCRM;
}
@Override
public String toString() {
return "Especialidade{" + nome + " / " + codigoCRM + "}";
}
}
// Plano de Saúde
static class PlanoSaude {
private String razaoSocial;
private String cnpj;
private String endereco;
private String telefone;
public PlanoSaude(String razaoSocial, String cnpj, String endereco, String telefone) {
this.razaoSocial = razaoSocial;
this.cnpj = cnpj;
this.endereco = endereco;
this.telefone = telefone;
}
public String getRazaoSocial() {
return razaoSocial;
}
public String getCnpj() {
return cnpj;
}
public String getEndereco() {
return endereco;
}
public String getTelefone() {
return telefone;
}
@Override
public String toString() {
return "PlanoSaude{" + razaoSocial + " / CNPJ:" + cnpj + "}";
}
}
// Horário de atendimento
static class Horario {
private LocalTime inicio;
private LocalTime fim;
public Horario(LocalTime inicio, LocalTime fim) {
if (inicio == null || fim == null) {
throw new IllegalArgumentException("Inicio e fim não podem ser nulos.");
}
if (fim.isBefore(inicio) || fim.equals(inicio)) {
throw new IllegalArgumentException("Fim deve ser depois do início.");
}
this.inicio = inicio;
this.fim = fim;
}
public LocalTime getInicio() {
return inicio;
}
public LocalTime getFim() {
return fim;
}
public boolean contem(LocalTime hora) {
return !hora.isBefore(inicio) && hora.isBefore(fim);
}
@Override
public String toString() {
return inicio + " - " + fim;
}
}
// Médico (subclasse de Pessoa)
static class Medico extends Pessoa {
private String crm;
private Map<DayOfWeek, Horario> horarios = new HashMap<>();
private List<Especialidade> especialidades = new ArrayList<>();
private List<PlanoSaude> convenios = new ArrayList<>();
// Construtores sobrecarregados
public Medico(String nome, String endereco, String telefone, String crm) {
super(nome, endereco, telefone);
this.crm = crm;
}
public Medico(String nome, String telefone, String crm) {
super(nome, null, telefone);
this.crm = crm;
}
public String getCrm() {
return crm;
}
public void setCrm(String crm) {
this.crm = crm;
}
public void addHorario(DayOfWeek dia, Horario horario) {
horarios.put(dia, horario);
}
public void addEspecialidade(Especialidade esp) {
if (esp != null) especialidades.add(esp);
}
public void addConvenio(PlanoSaude plano) {
if (plano != null) convenios.add(plano);
}
public boolean isConveniadoCom(PlanoSaude plano) {
return convenios.contains(plano);
}
public boolean isDisponivelEm(LocalDateTime dataHora) {
Horario h = horarios.get(dataHora.getDayOfWeek());
if (h == null) return false;
return h.contem(dataHora.toLocalTime());
}
/**
* Retorna todas as observações de consultas anteriores do paciente que foram
* feitas por este mesmo médico.
*/
public List<Observacao> consultarObservacoesAnteriores(Paciente paciente) {
List<Observacao> resultado = new ArrayList<>();
for (Consulta c : paciente.getConsultas()) {
if (c.getMedico() == this) { // compara referência; se preferir, compare crm
resultado.addAll(c.getObservacoes());
}
}
return resultado;
}
@Override
public String toString() {
return "Medico{" +
"nome='" + getNome() + '\'' +
", crm='" + crm + '\'' +
", telefone='" + getTelefone() + '\'' +
", endereco='" + getEndereco() + '\'' +
", especialidades=" + especialidades +
", convenios=" + convenios +
", horarios=" + horarios +
'}';
}
}
// Paciente (subclasse de Pessoa)
static class Paciente extends Pessoa {
private LocalDate dataNascimento;
private String profissao;
private List<Consulta> consultas = new ArrayList<>();
// Construtores sobrecarregados
public Paciente(String nome, String telefone) {
super(nome, null, telefone);
}
public Paciente(String nome, String telefone, LocalDate dataNascimento, String endereco, String profissao) {
super(nome, endereco, telefone);
this.dataNascimento = dataNascimento;
this.profissao = profissao;
}
public LocalDate getDataNascimento() {
return dataNascimento;
}
public void setDataNascimento(LocalDate dataNascimento) {
this.dataNascimento = dataNascimento;
}
public String getProfissao() {
return profissao;
}
public void setProfissao(String profissao) {
this.profissao = profissao;
}
public void adicionarConsulta(Consulta consulta) {
if (consulta != null) consultas.add(consulta);
}
public List<Consulta> getConsultas() {
return Collections.unmodifiableList(consultas);
}
@Override
public String toString() {
return "Paciente{" +
"nome='" + getNome() + '\'' +
", telefone='" + getTelefone() + '\'' +
", endereco='" + getEndereco() + '\'' +
", dataNascimento=" + dataNascimento +
", profissao='" + profissao + '\'' +
'}';
}
}
// Enum para tipos de observação
enum ObservacaoTipo {
QUEIXA,
PRESCRICAO,
RESULTADO
}
// Observação registrada numa consulta
static class Observacao {
private ObservacaoTipo tipo;
private String texto;
private LocalDateTime timestamp;
public Observacao(ObservacaoTipo tipo, String texto) {
this.tipo = tipo;
this.texto = texto;
this.timestamp = LocalDateTime.now();
}
public ObservacaoTipo getTipo() {
return tipo;
}
public String getTexto() {
return texto;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
@Override
public String toString() {
return "[" + timestamp + "] " + tipo + ": " + texto;
}
}
// Consulta entre paciente e médico
static class Consulta {
private Paciente paciente;
private Medico medico;
private LocalDateTime dataHora;
private PlanoSaude plano; // pode ser null (particular)
private List<Observacao> observacoes = new ArrayList<>();
public Consulta(Paciente paciente, Medico medico, LocalDateTime dataHora, PlanoSaude plano) {
this.paciente = paciente;
this.medico = medico;
this.dataHora = dataHora;
this.plano = plano;
}
public Paciente getPaciente() {
return paciente;
}
public Medico getMedico() {
return medico;
}
public LocalDateTime getDataHora() {
return dataHora;
}
public PlanoSaude getPlano() {
return plano;
}
public void adicionarObservacao(Observacao obs) {
if (obs != null) observacoes.add(obs);
}
public List<Observacao> getObservacoes() {
return Collections.unmodifiableList(observacoes);
}
public List<Observacao> listarObservacoes() {
return getObservacoes();
}
public List<Observacao> obterObservacoesPorTipo(ObservacaoTipo tipo) {
List<Observacao> res = new ArrayList<>();
for (Observacao o : observacoes) {
if (o.getTipo() == tipo) res.add(o);
}
return res;
}
@Override
public String toString() {
return "Consulta{" +
"paciente=" + paciente.getNome() +
", medico=" + medico.getNome() +
", dataHora=" + dataHora +
", plano=" + (plano == null ? "Particular" : plano.getRazaoSocial()) +
'}';
}
}
}