Recap - Student Records
Part of the Object Oriented Programming section of Coddy's GO journey — lesson 51 of 107.
Challenge
EasyLet's build a Student Records system that demonstrates proper encapsulation. You'll create a student management structure where sensitive academic data is protected while still providing controlled access through well-designed methods.
You'll organize your code across two files:
student.go: Create aStudentstruct that protects sensitive information while exposing safe public data. The student'sNameshould be exported (publicly accessible), but theirgrade(float64) andstudentID(string) should be unexported to protect this sensitive information.Implement the following:
- A constructor
NewStudent(name, id string, initialGrade float64) *Studentthat creates a student. The initial grade should only be set if it's between 0 and 100 (inclusive); otherwise, default to 0. - A getter
Grade() float64that returns the current grade - A getter
StudentID() stringthat returns the student ID - A setter
SetGrade(newGrade float64) boolthat updates the grade only if the new value is between 0 and 100 (inclusive). Returntrueif the grade was updated,falseotherwise. - A method
Summary() stringthat returns the format:[Name] (ID: [studentID]) - Grade: [grade]
- A constructor
main.go: Read student information from input, create a student using the constructor, then perform grade operations. Display the student's summary after creation and after each grade update attempt.
The following inputs will be provided:
- Line 1: Student name
- Line 2: Student ID
- Line 3: Initial grade
- Line 4: First new grade to set
- Line 5: Second new grade to set
After creating the student, print their summary. Then attempt each grade update—if successful, print the updated summary; if rejected, print Invalid grade rejected. Format all grade values with two decimal places.
For example, given Emma Wilson, STU001, 85.5, 92.0, and 150, your output should be:
Emma Wilson (ID: STU001) - Grade: 85.50
Emma Wilson (ID: STU001) - Grade: 92.00
Invalid grade rejectedThe last update fails because 150 is outside the valid range. Your setter method enforces this rule, keeping the student's data valid. Notice how the studentID and grade are never directly accessible—external code must use your getter and setter methods to interact with this protected data.
Try it yourself
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Read student name
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
// Read student ID
id, _ := reader.ReadString('\n')
id = strings.TrimSpace(id)
// Read initial grade
initialGradeStr, _ := reader.ReadString('\n')
initialGrade, _ := strconv.ParseFloat(strings.TrimSpace(initialGradeStr), 64)
// Read first new grade
newGrade1Str, _ := reader.ReadString('\n')
newGrade1, _ := strconv.ParseFloat(strings.TrimSpace(newGrade1Str), 64)
// Read second new grade
newGrade2Str, _ := reader.ReadString('\n')
newGrade2, _ := strconv.ParseFloat(strings.TrimSpace(newGrade2Str), 64)
// TODO: Create a new student using NewStudent constructor
// TODO: Print the student's summary after creation
// TODO: Attempt first grade update
// If successful, print the updated summary
// If rejected, print "Invalid grade rejected"
// TODO: Attempt second grade update
// If successful, print the updated summary
// If rejected, print "Invalid grade rejected"
// Hint: Use fmt.Sprintf with %.2f for formatting grades in Summary()
_ = newGrade1 // Remove this line when you use the variable
_ = newGrade2 // Remove this line when you use the variable
}
All lessons in Object Oriented Programming
1Fundamentals of Go OOP
External FilesGo Workspace & ModulesPackages & ImportsExported vs Unexported NamesIntroduction to OOP in GoStructs as ClassesDefining Methods on StructsPointer vs Value ReceiversStruct InitializationConstructor FunctionsRecap - Simple Calculator4Interfaces
Introduction to InterfacesImplicit ImplementationInterface as ContractEmpty Interface (any)Type AssertionType SwitchInterface CompositionStringer & Error InterfacesRecap - Shape Calculator7Encapsulation
Exported vs Unexported FieldsPackage-Level EncapsulationGetter & Setter MethodsInformation Hiding in GoRecap - Student Records10Generics (Go 1.18+)
Introduction to GenericsType ParametersType ConstraintsGeneric StructsGeneric Methods WorkaroundRecap - Generic Collection2Types & Structs Deep Dive
Basic & Composite TypesCustom Type DefinitionsStruct TagsAnonymous StructsNested StructsZero Values & DefaultsRecap - Contact Book5Composition Over Inheritance
Why Go Has No InheritanceStruct Embedding BasicsMethod PromotionEmbedding Multiple StructsEmbedding vs AggregationShadowing Embedded MethodsRecap - Employee Hierarchy8Error Handling & OOP
The error InterfaceCustom Error TypesError Wrapping (fmt.Errorf)Sentinel Errorserrors.Is() and errors.As()Panic, Defer, and RecoverRecap - File Parser3Pointers & Memory
Pointer Basics in GoPointers to StructsPass by Value vs ReferenceThe new() FunctionGarbage Collection in GoRecap - Linked List Builder6Polymorphism in Go
Polymorphism via InterfacesDuck Typing in GoInterface Satisfaction RulesPolymorphic CollectionsDependency InjectionRecap - Payment Processor9Concurrency & OOP
Goroutines BasicsChannels & CommunicationBuffered vs Unbuffered ChanSelect Statementsync.Mutex & sync.RWMutexsync.WaitGroupThread-Safe Struct DesignRecap - Worker Pool