Private by Convention
Part of the Object Oriented Programming section of Coddy's GDScript journey. Lesson 13 of 65.
GDScript has no private keyword: every property and method of an object can be reached from other scripts. Godot's convention is a leading underscore. _coins and _is_valid() below are meant for the class's own code only:
# wallet.gd
class_name Wallet
extends RefCounted
var _coins: int = 0
func add(amount: int) -> void:
if _is_valid(amount):
_coins += amount
func spend(amount: int) -> bool:
if not _is_valid(amount) or amount > _coins:
return false
_coins -= amount
return true
func get_coins() -> int:
return _coins
func _is_valid(amount: int) -> bool:
return amount > 0Other scripts use the public methods, and those check every change: spend() refuses to take more coins than the wallet holds, so the number of coins never goes below zero.
var wallet := Wallet.new()
wallet.add(50)
wallet.add(-20)
print(wallet.spend(80)) # false
print(wallet.get_coins()) # 50The underscore is a promise, not a lock: wallet._coins = -999 runs without any error. Keeping the promise is up to whoever writes the other scripts, so do not read or change underscored members from outside their class.
You already know two underscore names from Godot itself: _ready() and _init() are called by the engine, not by your own code.
Challenge
EasyComplete the class User in user.gd. It keeps its password in a private property, _password, and only its own code touches it.
- The constructor stores the starting password
check_password(attempt)returns whetherattemptmatches the password_is_strong(candidate), a private helper, returns whethercandidatehas at least6characterschange_password(old_password, new_password)changes the password and returnstrueonly whenold_passwordis correct andnew_passwordis strong. Otherwise it changes nothing and returnsfalse
The supplied code reads the starting password, how many commands follow, and the commands check PASSWORD and change OLD NEW. For the password godot4 and the commands change godot4 abc, change wrong longenough and check godot4 it prints:
Password not changed
Password not changed
Access grantedYour code goes in user.gd. main.gd holds the supplied input/output code and cannot be edited.
Try it yourself
extends Node
func _ready():
# Supplied input/output code: keep it as it is
var user := User.new(OS.read_string_from_stdin())
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "check":
print("Access granted" if user.check_password(parts[1]) else "Access denied")
elif user.change_password(parts[1], parts[2]):
print("Password changed")
else:
print("Password not changed")
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe self KeywordMethodsPropertiesConstructor (_init)Recap - Simple Calculator4Polymorphism
Method Overriding RevisitedDuck TypingAbstract Classes and MethodsInterface DesignRecap - Shape Calculator2Class Properties
Instance vs Static VariablesStatic FunctionsProperty SettersProperty GettersPrivate by ConventionRecap - Bank Account Manager5Encapsulation
Public and Private MembersValidation with SettersInformation HidingRead-Only PropertiesRecap - Student Records System8Advanced OOP Concepts
Composition vs InheritanceInner ClassesNodes as ComponentsRefCounted vs NodeEnums in Classes11Project: Library Management
Project OverviewBook and User Classes3Inheritance
Basic InheritanceThe super KeywordMethod OverridingInheritance ChainsType Checks with isRecap - Employee Hierarchy6Special Methods
Virtual Methods IntroductionThe _to_string MethodCustom IteratorsRecap - Custom List9Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy PatternPractice on your own: Online GDScript compiler