Miembros públicos y privados
Parte de la sección Programación orientada a objetos del Journey de GDScript de Coddy. Lección 26 de 65.
Encapsulación significa que un objeto mantiene sus datos junto con los métodos que los modifican y decide cuáles de sus miembros puede usar otro código. Los miembros destinados a otros códigos forman la interfaz del objeto.
GDScript no tiene la palabra clave public ni private: se puede acceder a todos los miembros desde el exterior. La guía de estilo de Godot marca los privados con un guion bajo al principio:
# 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() y get_balance() son públicos, así que main.gd los usa. _balance, _history y _record() son privados: solo el código dentro de bank_account.gd los usa.
# main.gd
var account := BankAccount.new("Ada")
account.deposit(50)
account.deposit(20)
print(account.owner_name) # Ada
print(account.get_balance()) # 70El guion bajo es una convención, no un bloqueo: account._balance = 1000000 en main.gd se ejecuta sin ningún error. Aun así, respeta la convención. Cuando solo la clase modifica _balance, un saldo incorrecto solo puede deberse a un método de bank_account.gd, así que ese es el único archivo que tienes que revisar.
GDScript tampoco tiene un nivel protected. Una subclase hereda todos los miembros, incluidos los privados, así que una SavingsAccount que extends BankAccount puede usar _balance en sus propios métodos.
Los métodos virtuales de Godot, como _init() y _ready(), también empiezan con un guion bajo. Godot los llama por ti, así que nunca le des el mismo nombre a uno de tus métodos privados.
Desafío
FácilTermina la clase Hero en hero.gd. Sus miembros públicos son hero_name, gain_xp(), get_xp() y get_level(). El resto es privado:
- Añade las variables privadas
_xp(empieza en0) y_level(empieza en1). - Añade el método privado
_update_level(), que establece_levelen1 + _xp / 100(división entera). gain_xp(amount)sumaamounta_xp, llama a_update_level()y devuelvetruecuando el nivel sube, yfalseen caso contrario.get_xp()yget_level()devuelven los valores privados.
El código proporcionado lee el nombre del héroe, luego cuántas cantidades de XP siguen y, después, una cantidad por línea. Después de cada cantidad, imprime una línea Level up! cuando gain_xp() devuelve true, y luego el estado del héroe. Para Ada y las cantidades 40, 70 y 250, imprime:
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 4Tu código va en hero.gd. main.gd contiene el código de entrada/salida proporcionado y no se puede editar.
Pruébalo tú mismo
extends Node
func _ready():
# Código de entrada/salida proporcionado: mantenlo tal como está
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()])
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Fundamentos de la programación orientada a objetos
Archivos externosIntroducción a la programación orientada a objetosClases vs. objetosLa palabra clave selfMétodosPropiedadesConstructor (_init)Repaso: calculadora sencilla4Polimorfismo
Repaso de la sobrescritura de métodosTipado patoClases y métodos abstractosDiseño de interfacesRepaso: calculadora de formas7Señales
¿Qué es una señal?Declarar y emitirConectarse a las señalesSeñales con argumentosRepaso: sistema de salud10Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite2Propiedades de clase
Variables de instancia y estáticasFunciones estáticasMétodos setter de propiedadesMétodos getter de propiedadesPrivado por convenciónRepaso: administrador de cuentas bancarias5Encapsulación
Miembros públicos y privadosValidación con settersOcultación de informaciónPropiedades de solo lecturaRepaso: sistema de registros de estudiantes8Conceptos avanzados de POO
Composición frente a herenciaClases internasNodos como componentesRefCounted frente a NodeEnums en clases3Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosCadenas de herenciaComprobaciones de tipo con isRepaso: jerarquía de empleados6Métodos especiales
Introducción a los métodos virtualesEl método _to_stringIteradores personalizadosRepaso: lista personalizada9Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de GDScript online