Recapitulação - Registros de Estudantes
Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy — lição 51 de 107.
Desafio
FácilVamos construir um sistema de Registros de Alunos que demonstra o encapsulamento adequado. Você criará uma estrutura de gerenciamento de alunos onde dados acadêmicos sensíveis são protegidos, enquanto ainda fornece acesso controlado por meio de métodos bem projetados.
Você organizará seu código em dois arquivos:
student.go: Crie uma structStudentque proteja informações sensíveis enquanto expõe dados públicos seguros. ONamedo aluno deve ser exportado (acessível publicamente), mas seugrade(float64) estudentID(string) devem ser não exportados para proteger essas informações sensíveis.Implemente o seguinte:
- Um construtor
NewStudent(name, id string, initialGrade float64) *Studentque cria um aluno. A nota inicial só deve ser definida se estiver entre 0 e 100 (inclusive); caso contrário, o padrão deve ser 0. - Um getter
Grade() float64que retorna a nota atual - Um getter
StudentID() stringque retorna o ID do aluno - Um setter
SetGrade(newGrade float64) boolque atualiza a nota apenas se o novo valor estiver entre 0 e 100 (inclusive). Retornetruese a nota foi atualizada,falsecaso contrário. - Um método
Summary() stringque retorna o formato:[Name] (ID: [studentID]) - Grade: [grade]
- Um construtor
main.go: Leia as informações do aluno da entrada, crie um aluno usando o construtor e, em seguida, realize operações de nota. Exiba o resumo do aluno após a criação e após cada tentativa de atualização de nota.
As seguintes entradas serão fornecidas:
- Linha 1: Nome do aluno
- Linha 2: ID do aluno
- Linha 3: Nota inicial
- Linha 4: Primeira nova nota a ser definida
- Linha 5: Segunda nova nota a ser definida
Após criar o aluno, imprima seu resumo. Em seguida, tente cada atualização de nota — se for bem-sucedida, imprima o resumo atualizado; se for rejeitada, imprima Invalid grade rejected. Formate todos os valores de nota com duas casas decimais.
Por exemplo, dados Emma Wilson, STU001, 85.5, 92.0 e 150, sua saída deve ser:
Emma Wilson (ID: STU001) - Grade: 85.50
Emma Wilson (ID: STU001) - Grade: 92.00
Invalid grade rejectedA última atualização falha porque 150 está fora do intervalo válido. Seu método setter impõe essa regra, mantendo os dados do aluno válidos. Observe como o studentID e a grade nunca são acessíveis diretamente — o código externo deve usar seus métodos getter e setter para interagir com esses dados protegidos.
Experimente você mesmo
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Ler o nome do estudante
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
// Ler o ID do estudante
id, _ := reader.ReadString('\n')
id = strings.TrimSpace(id)
// Ler a nota inicial
initialGradeStr, _ := reader.ReadString('\n')
initialGrade, _ := strconv.ParseFloat(strings.TrimSpace(initialGradeStr), 64)
// Ler a primeira nova nota
newGrade1Str, _ := reader.ReadString('\n')
newGrade1, _ := strconv.ParseFloat(strings.TrimSpace(newGrade1Str), 64)
// Ler a segunda nova nota
newGrade2Str, _ := reader.ReadString('\n')
newGrade2, _ := strconv.ParseFloat(strings.TrimSpace(newGrade2Str), 64)
// TODO: Criar um novo estudante usando o construtor NewStudent
// TODO: Imprimir o resumo do estudante após a criação
// TODO: Tentar a primeira atualização de nota
// Se for bem-sucedido, imprima o resumo atualizado
// Se for rejeitado, imprima "Invalid grade rejected"
// TODO: Tentar a segunda atualização de nota
// Se for bem-sucedido, imprima o resumo atualizado
// Se for rejeitado, imprima "Invalid grade rejected"
// Hint: Use fmt.Sprintf com %.2f para formatar as notas em Summary()
_ = newGrade1 // Remova esta linha quando você usar a variável
_ = newGrade2 // Remova esta linha quando você usar a variável
}
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP em Go
Arquivos ExternosGo Workspace e MódulosPacotes e ImportaçõesNomes Exportados vs Não ExportadosIntrodução a OOP em GoStructs como ClassesDefinindo Métodos em StructsRecebedores de Ponteiro vs ValorInicialização de StructsFunções ConstrutorasRecapitulação - Calculadora Simples4Interfaces
Introdução a InterfacesImplementação ImplícitaInterface como ContratoInterface Vazia (any)Type AssertionType SwitchComposição de InterfacesInterfaces Stringer & ErrorRecapitulação - Calculadora de Formas7Encapsulamento
Campos Exportados vs Não ExportadosEncapsulamento em Nível de PacoteMétodos Getter e SetterOcultação de Informação em GoRecapitulação - Registros de Estudantes10Generics (Go 1.18+)
Introdução a GenericsParâmetros de TipoRestrições de TipoStructs GenéricasSolução Alternativa para Métodos GenéricosRecapitulação - Coleção Genérica2Mergulho Profundo em Tipos e Structs
Tipos Básicos e CompostosDefinições de Tipos PersonalizadosStruct TagsStructs AnônimasStructs AninhadasZero Values e PadrõesRecapitulação - Agenda de Contatos5Composição em vez de Herança
Por que Go não possui HerançaFundamentos de Incorporação de StructsPromoção de MétodosIncorporando Múltiplas StructsIncorporação vs AgregaçãoShadowing de Métodos IncorporadosRecapitulação - Hierarquia de Funcionários8Tratamento de Erros e OOP
A Interface errorTipos de Erro PersonalizadosError Wrapping (fmt.Errorf)Erros Sentinelaerrors.Is() e errors.As()Panic, Defer e RecoverRecapitulação - File Parser3Ponteiros e Memória
Fundamentos de Ponteiros em GoPonteiros para StructsPassagem por Valor vs ReferênciaA Função new()Garbage Collection em GoRecapitulação - Construtor de Lista Encadeada6Polimorfismo em Go
Polimorfismo via InterfacesDuck Typing em GoRegras de Satisfação de InterfaceColeções PolimórficasInjeção de DependênciaRecapitulação - Processador de Pagamentos9Concorrência e OOP
Fundamentos de GoroutinesCanais e ComunicaçãoCanais com Buffer vs. Sem BufferInstrução Selectsync.Mutex e sync.RWMutexsync.WaitGroupDesign de Structs Thread-SafeRecapitulação - Worker Pool