Utilizando ArrayList Tipado em Java

Eu preciso criar um pequeno programa utilizando ArrayList e estou com muitas duvidas:
O programa é um sistema de controle de ponto que deverá possuir o seguinte menu:

[1] Consultar dados de uma pessoa
[2] Cadastrar novo aluno
[3] Cadastrar novo professor
[4] Cadastrar novo administrativo
[0] Sair

Sendo que eu criei as seguintes classes para antender:

public abstract class Pessoa {

    private final String nome;
    private final String cpf;
    private final String matricula;

    //construtor
    public Pessoa (String nome, String cpf, String matricula) {
        this.nome = nome;
        this.cpf = cpf;
        this.matricula = matricula;
    }


    public String getNome(){
        return nome;
    }

    public String getCpf(){
        return cpf;
    }

    public String getMatricula (){
        return matricula;
    }

    @Override
    public String toString(){
        return String.format("%s %s%nInformações da Pessoa: %s", getNome(), getCpf(), getMatricula());
    }

}

import java.util.ArrayList;


public class Aluno extends Pessoa{

    private ArrayList<Curso> cursos = new ArrayList<>(Curso);

    //construtor
    public Aluno (String nome, String cpf, String matricula,ArrayList<Curso> cursos){

        super(nome,cpf,matricula); //construtor da superclasse

        Curso curso = new Curso (cursos); //construtor da classe Curso passando o arraylist

    }

    public ArrayList<Curso> getCursos{
        return cursos;

    }

    @Override
    public String toString(){

        return String.format("Os alunos são",super.toString(),"Os cursos são:",getCursos);

    }


}

import java.util.ArrayList;

public class Professor extends Pessoa{

    private ArrayList<Curso> cursos = new ArrayList<>(Curso);
    private double salario;
    private final int hora_aula = 40;


    public Professor(String nome, String cpf, String matricula,ArrayList<Curso> cursos,double salario) {

        super(nome, cpf, matricula); //construtor da superclasse
        Curso curso = new Curso (cursos); //construtor da classe Curso passando o arraylist
        this.salario = salario;

    }

    public double getSalario(){

        //Para o calculo do salário do professor, precisa pegar o montante do total de horas aula do curso * Hora_aula (40)
        //Como eu resgato isso no arraylist cursos?
        return salario;
    }

    public ArrayList<Curso> getCursos{
        return cursos;

    }

    @Override
    public String toString(){
        return String.format("Professor: %s%n%s: $%,.2f",super.toString(), "Salario", getSalario(),"Cursos",getCursos);
    }

}

public class Administrativo extends Pessoa {

    private double salario;

    //construtor
    public Administrativo (String nome, String cpf, String matricula,double salario){

        super (nome,cpf,matricula); //construtor da superclasse

        if (salario < 0.0)
            throw new IllegalArgumentException("Salário deve ser maior que 0.0");

        this.salario = salario;

    }

    public double getSalario(){
        return salario;
    }

    @Override
    public String toString(){
        return String.format("Funcionário: %s%n%s: $%,.2f",super.toString(), "Salario", getSalario());
    }

}

import java.util.ArrayList;

public class Curso {

    private String nome;
    private int horas;

    //construtor

    public Curso(ArrayList<Curso> cursos) {

        // como atribuir valores do arraylist de curso nos atributos da classe?
       // this.nome = cursos
       // this.horas = cursos

    }

    public String getnome(){
        return  nome;

    }

    public int gethoras(){
        return horas;

    }

    // Precisa de toString?

    }

A dúvida é na classe Aluno:

Como eu receberia o ArrayList de Curso e depois passaria os dados dele para o construtor da classe Curso?

Entramos num dilema, o que seria o ideal, uma lista de cursos para cada aluno ou uma lista de alunos para um determinado curso?

O que não faz muito sentido é um curso receber uma lista de cursos…

Outra dica, procure usar List do lado esquerdo do sinal de igual, e use ArrayList do lado direito onde houver new…

blz. Muito obrigado pela ajuda.

Agora, como eu faço para imprimir o nome do aluno e seus cursos na opção 2 desse menu:
No caso quando o usuário cadastrar o aluno e seus cursos, quando ele escolher a oçção zero do submenu, o programa terá que apresentar o nome do aluno e seus cursos.
Está rodando, mas não está aparecendo o conteudo do objeto.

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

public class Principal {

public static void apresentarMenu(){

    System.out.println("[1] Consultar dados de uma pessoa");
    System.out.println("[2] Cadastrar novo aluno");
    System.out.println("[3] Cadastrar novo professor");
    System.out.println("[4] Consultar novo administrativo");
    System.out.println("[0] Sair");
    System.out.print("Informe a opçao desejada:");
}


public static void apresentaSubMenu(){
    System.out.println("[1] Inserir novo curso");
    System.out.println("[0] Finalizar");
    System.out.print("Informe a opçao desejada:");
}


public static void main(String[] args) {

    Aluno aluno = null;
    ArrayList<Pessoa> pessoas = new ArrayList<Pessoa>();
    Scanner input = new Scanner(System.in);
    String op = "1";

    while (op != "0"){

        apresentarMenu();
        op = String.valueOf(input.nextInt());

        switch (op){
            case "1":
                System.out.print("Informe a matricula");
                String mat = input.next();
                //connsultar os dados do aluno
                break;

            case "2":
                System.out.println("Informe o nome do aluno");
                String nome = input.next();

                System.out.println("Informe o CPF do aluno");
                String cpf = input.next();

                System.out.println("Informe a matricula do aluno");
                String matricula = input.next();

                apresentaSubMenu();
                int opsubmenu = input.nextInt();

                while (opsubmenu != 0){

                    if (opsubmenu == 1) {
                        System.out.println("Informe o nome do curso:");
                        String nomecurso = input.next();

                        System.out.println("Informe a carga horária do curso");
                        int horacurso = input.nextInt();

                        aluno = new Aluno(nome, cpf, matricula, nomecurso, horacurso);
                        apresentaSubMenu();
                        opsubmenu  = input.nextInt();
                    }
                }

                if (opsubmenu == 0){
                    pessoas.add(aluno);
                    for (Pessoa currentPessoa : pessoas ){

                        Aluno pessoa = (Aluno) currentPessoa;
                        System.out.println(currentPessoa.toString());
                    }

                }
                break;


        }





    }


}

}

Seria melhor você criar outro tópico para essa dúvida, já que não se trata mais de ArrayList… assim também esse tópico não fica “muito cheio”…