Membri pubblici e privati
Fa parte della sezione Programmazione orientata agli oggetti del percorso GDScript di Coddy. Lezione 26 di 65.
L'incapsulamento significa che un oggetto mantiene i propri dati insieme ai metodi che li modificano e decide quali dei suoi membri possono essere usati da altro codice. I membri destinati a essere usati da altro codice costituiscono l'interfaccia dell'oggetto.
GDScript non ha parole chiave public o private: ogni membro può essere raggiunto dall'esterno. La guida di stile di Godot contrassegna quelli privati con un trattino basso iniziale:
# bank_account.gd
class_name BankAccount
extends RefCounted
var owner_name: String
var _balance: int = 0
var _history: Array[String] = []
func _init(holder: String) -> void:
owner_name = holder
func deposit(amount: int) -> void:
_balance += amount
_record("deposit %d" % amount)
func get_balance() -> int:
return _balance
func _record(entry: String) -> void:
_history.append(entry)owner_name, deposit() e get_balance() sono pubblici, quindi main.gd li usa. _balance, _history e _record() sono privati: li usa solo il codice all'interno di bank_account.gd.
# main.gd
var account := BankAccount.new("Ada")
account.deposit(50)
account.deposit(20)
print(account.owner_name) # Ada
print(account.get_balance()) # 70Il trattino basso è una convenzione, non un blocco: account._balance = 1000000 in main.gd viene eseguito senza errori. Rispetta comunque la convenzione. Se solo la classe modifica _balance, un saldo errato può provenire solo da un metodo in bank_account.gd, quindi è l’unico file che devi controllare.
Anche GDScript non ha un livello protected. Una sottoclasse eredita tutti i membri, inclusi quelli privati, quindi una SavingsAccount che extends BankAccount può usare _balance nei propri metodi.
Anche i metodi virtuali di Godot, come _init() e _ready(), iniziano con un trattino basso. Godot li chiama per te, quindi non dare mai lo stesso nome a uno dei tuoi metodi privati.
Sfida
FacileCompleta la classe Hero in hero.gd. I suoi membri pubblici sono hero_name, gain_xp(), get_xp() e get_level(). Il resto è privato:
- Aggiungi le variabili private
_xp(inizia da0) e_level(inizia da1). - Aggiungi il metodo privato
_update_level(), che imposta_levelsu1 + _xp / 100(divisione intera). gain_xp(amount)aggiungeamounta_xp, chiama_update_level()e restituiscetruequando il livello è aumentato, altrimentifalse.get_xp()eget_level()restituiscono i valori privati.
Il codice fornito legge il nome dell'eroe, poi quanti valori di XP seguono, quindi un valore per riga. Dopo ogni valore stampa una riga Level up! quando gain_xp() restituisce true, poi lo stato dell'eroe. Per Ada e i valori 40, 70 e 250 stampa:
Ada: 40 XP, level 1
Level up! Ada is now level 2
Ada: 110 XP, level 2
Level up! Ada is now level 4
Ada: 360 XP, level 4Il tuo codice va in hero.gd. main.gd contiene il codice fornito per l'input/output e non può essere modificato.
Provalo tu
extends Node
func _ready():
# Codice di input/output fornito: lascialo così com'è
var hero := Hero.new(OS.read_string_from_stdin())
var count := int(OS.read_string_from_stdin())
for i in count:
var amount := int(OS.read_string_from_stdin())
if hero.gain_xp(amount):
print("Level up! %s is now level %d" % [hero.hero_name, hero.get_level()])
print("%s: %d XP, level %d" % [hero.hero_name, hero.get_xp(), hero.get_level()])
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniIntroduzione alla programmazione orientata agli oggettiClassi e oggetti a confrontoLa parola chiave selfMetodiProprietàCostruttore (_init)Riepilogo - Calcolatrice semplice4Polimorfismo
Ripasso dell'override dei metodiDuck typingClassi e metodi astrattiProgettazione delle interfacceRiepilogo - Calcolatore di forme7Segnali
Che cos'è un segnale?Dichiarare ed emettereCollegarsi ai segnaliSegnali con argomentiRipasso - Sistema della salute10Pattern di progettazione, parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern Composite2Proprietà delle classi
Variabili di istanza e staticheFunzioni staticheSetter delle proprietàGetter delle proprietàPrivato per convenzioneRiepilogo - Gestore di conti bancari5Incapsulamento
Membri pubblici e privatiValidazione con i setterNascondimento delle informazioniProprietà di sola letturaRiepilogo - Sistema di gestione dei dati degli studenti8Concetti avanzati di OOP
Composizione vs ereditarietàClassi interneNodi come componentiRefCounted vs NodeEnum nelle classi11Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente3Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiCatene di ereditarietàControlli di tipo con isRipasso - Gerarchia dei dipendenti6Metodi speciali
Introduzione ai metodi virtualiIl metodo _to_stringIteratori personalizzatiRiepilogo - Lista personalizzata9Modelli di progettazione, parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern ObserverPattern StrategyEsercitati da solo: Compilatore GDScript online