Menu
Coddy logo textTech

Plataforma de E-Learning

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 84 de 87.

Bem-vindo ao capítulo de Desafios Finais! Estes desafios foram projetados para testar seu domínio de todos os conceitos de POO que você aprendeu ao longo deste curso.

Neste desafio, você construirá um sistema de Plataforma de E-Learning que combina herança, interfaces, polimorfismo, encapsulamento e padrões de projeto em uma aplicação coesa.

Sua plataforma deve modelar os relacionamentos entre cursos, alunos e instrutores. Pense em como uma classe base User pode ser estendida pelas classes Student e Instructor, como os cursos contêm lições e como o rastreamento de matrículas funciona entre alunos e cursos.

Considere quais princípios de POO se aplicam: use encapsulamento para proteger os dados do usuário, herança para compartilhar comportamentos comuns, interfaces para definir contratos como Enrollable ou Completable, e polimorfismo para lidar com diferentes tipos de usuários de forma uniforme.

Boa sorte ao aplicar tudo o que você aprendeu!

challenge icon

Desafio

Fácil

Vamos construir uma Plataforma de E-Learning que reúne todos os conceitos de POO que você dominou ao longo deste curso! Você criará um sistema que modela as relações entre cursos, alunos e instrutores usando herança, interfaces, polimorfismo e encapsulamento.

Você organizará seu código em seis arquivos:

  • Enrollable.java: Crie uma interface que define o contrato para operações de matrícula. Ela deve declarar os métodos enroll(Student student) que retorna um boolean, e getEnrolledCount() que retorna um int.
  • User.java: Crie uma classe base abstrata representando qualquer usuário na plataforma. Inclua campos privados para id (String) e name (String), um construtor que inicializa ambos, getters apropriados e um método abstrato getRole() que retorna uma String descrevendo o papel do usuário.
  • Student.java: Crie uma classe que estende User. Adicione um ArrayList privado para rastrear os IDs dos cursos matriculados. Inclua um construtor que chama o construtor pai, implemente getRole() para retornar "Student" e adicione os métodos addCourse(String courseId) e getEnrolledCourseCount(). Sobrescreva toString() para retornar "Student: [name] ([enrolledCount] courses)".
  • Instructor.java: Crie uma classe que estende User. Adicione um campo privado para specialty (String). Inclua um construtor que recebe id, name e specialty, implemente getRole() para retornar "Instructor", adicione um getter para specialty e sobrescreva toString() para retornar "Instructor: [name] - [specialty]".
  • Course.java: Crie uma classe que implementa Enrollable. Inclua campos privados para courseId (String), title (String), instructor (Instructor) e um ArrayList de Students matriculados. O construtor recebe courseId, title e instructor. Implemente enroll(Student student) para adicionar o aluno à lista, chame o método addCourse() do aluno com o ID deste curso e retorne true. Implemente getEnrolledCount(). Adicione um método getDetails() que retorna "[courseId] [title] by [instructorName]".
  • Main.java: Construa sua plataforma! Você receberá uma string de comandos separados por vírgula:
    • ADD_INSTRUCTOR:id:name:specialty
    • ADD_STUDENT:id:name
    • ADD_COURSE:courseId:title:instructorId
    • ENROLL:studentId:courseId
    • INFO:userId

    Mantenha coleções de instrutores, alunos e cursos. Processe cada comando e imprima:

    • ADD_INSTRUCTOR: Instructor added: [name]
    • ADD_STUDENT: Student added: [name]
    • ADD_COURSE: Course added: [title]
    • ENROLL: [studentName] enrolled in [courseTitle]
    • INFO: Imprima a saída do toString() do usuário

    Após todos os comandos, imprima --- Platform Summary --- seguido pelos detalhes de cada curso e a contagem de matrículas no formato [courseDetails] - [count] student(s).

Você receberá uma entrada: a string de comando separada por vírgulas.

Por exemplo, com a entrada ADD_INSTRUCTOR:I001:Dr. Smith:Java,ADD_STUDENT:S001:Alice,ADD_STUDENT:S002:Bob,ADD_COURSE:C001:OOP Fundamentals:I001,ENROLL:S001:C001,ENROLL:S002:C001,INFO:S001,INFO:I001, sua saída seria:

Instructor added: Dr. Smith
Student added: Alice
Student added: Bob
Course added: OOP Fundamentals
Alice enrolled in OOP Fundamentals
Bob enrolled in OOP Fundamentals
Student: Alice (1 courses)
Instructor: Dr. Smith - Java
--- Platform Summary ---
[C001] OOP Fundamentals by Dr. Smith - 2 student(s)

Este desafio combina herança (hierarquia User), interfaces (Enrollable), polimorfismo (diferentes tipos de usuários com suas próprias implementações de toString) e encapsulamento (campos privados com acesso controlado) em um sistema coeso!

Folha de consulta

Este desafio final combina múltiplos conceitos de POO em um sistema coeso:

Interfaces

Defina contratos para comportamentos que as classes devem implementar:

public interface Enrollable {
    boolean enroll(Student student);
    int getEnrolledCount();
}

Classes Abstratas

Crie classes base com comportamento compartilhado e métodos abstratos:

public abstract class User {
    private String id;
    private String name;
    
    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }
    
    public abstract String getRole();
}

Herança

Estenda classes base para criar tipos especializados:

public class Student extends User {
    private ArrayList<String> enrolledCourses;
    
    public Student(String id, String name) {
        super(id, name);
        this.enrolledCourses = new ArrayList<>();
    }
    
    @Override
    public String getRole() {
        return "Student";
    }
}

Implementando Interfaces

As classes podem implementar interfaces para cumprir contratos:

public class Course implements Enrollable {
    private ArrayList<Student> enrolledStudents;
    
    @Override
    public boolean enroll(Student student) {
        enrolledStudents.add(student);
        student.addCourse(courseId);
        return true;
    }
    
    @Override
    public int getEnrolledCount() {
        return enrolledStudents.size();
    }
}

Polimorfismo

Diferentes classes podem sobrescrever métodos para fornecer comportamento especializado:

@Override
public String toString() {
    return "Student: " + name + " (" + enrolledCourses.size() + " courses)";
}

Encapsulamento

Use campos privados com acesso controlado por meio de métodos para proteger a integridade dos dados e manter relacionamentos entre objetos.

Experimente você mesmo

import java.util.Scanner;
import java.util.HashMap;
import java.util.ArrayList;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: Criar coleções para armazenar instrutores, alunos e cursos
        // Dica: Use HashMap com id como chave para facilitar a busca
        
        // TODO: Dividir a entrada por vírgula para obter comandos individuais
        
        // TODO: Processar cada comando:
        // - ADD_INSTRUCTOR:id:name:specialty -> Criar instrutor, adicionar à coleção, imprimir "Instructor added: [name]"
        // - ADD_STUDENT:id:name -> Criar aluno, adicionar à coleção, imprimir "Student added: [name]"
        // - ADD_COURSE:courseId:title:instructorId -> Criar curso com instrutor, adicionar à coleção, imprimir "Course added: [title]"
        // - ENROLL:studentId:courseId -> Matricular aluno no curso, imprimir "[studentName] enrolled in [courseTitle]"
        // - INFO:userId -> Encontrar usuário (aluno ou instrutor) e imprimir seu toString()
        
        // TODO: Após processar todos os comandos, imprimir "--- Platform Summary ---"
        
        // TODO: Para cada curso, imprimir "[courseDetails] - [count] student(s)"
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos