Menu
CoddyTech

Read-Only Properties

Part of the Object Oriented Programming section of Coddy's GDScript journey. Lesson 29 of 65.

Some values should be readable from outside but never assigned: an ID given once when the object is created, or a value worked out from other data, such as an area or a total. A property with a get block and no set block does that:

# ticket.gd
class_name Ticket
extends RefCounted

var _number: int
var number: int:
	get:
		return _number

func _init(start_number: int) -> void:
	_number = start_number

The constructor stores the value in the private _number, and the public number only returns it. Assigning to number from outside is not an error, but it changes nothing, because the getter keeps returning _number:

var ticket := Ticket.new(42)
ticket.number = 7
print(ticket.number) # 42

A computed property has no value of its own: its getter works the value out each time it is read, so it always matches the data it comes from:

# room.gd
class_name Room
extends RefCounted

var width: int = 4
var length: int = 5
var area: int:
	get:
		return width * length
var room := Room.new()
print(room.area) # 20
room.width = 6
print(room.area) # 30

A plain var area would have to be updated by hand every time width or length changes, and one forgotten update leaves it wrong. The computed area cannot get out of date, and nobody can assign a wrong value to it.

For a value that is the same for every object and never changes, use a constant in the class: const MAX_GUESTS = 4. Assigning to a constant is reported before the program runs.

challenge icon

Challenge

Easy

The Order class in order.gd stores its ID in _id and the total of each line in _line_totals (price times quantity). Make its four public properties read-only with get blocks:

  • order_id returns _id.
  • subtotal returns the sum of _line_totals.
  • shipping returns 0 when the subtotal is 50 or more, otherwise 5.
  • total returns the subtotal plus the shipping.

The supplied code reads the order ID, the number of items, then one price quantity line per item. After each item it prints the subtotal, shipping and total. At the end it tries to set all four properties to 0, then prints the ID and the total, which must be unchanged. For the ID 7 and the items 12 2 and 30 1 it prints:

Subtotal 24, shipping 5, total 29
Subtotal 54, shipping 0, total 54
Order #7: 54

Your code goes in order.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 order := Order.new(int(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(" ")
		order.add_item(int(parts[0]), int(parts[1]))
		print("Subtotal %d, shipping %d, total %d" % [order.subtotal, order.shipping, order.total])
	# Code that tries to overwrite the read-only properties
	order.order_id = 0
	order.subtotal = 0
	order.shipping = 0
	order.total = 0
	print("Order #%d: %d" % [order.order_id, order.total])
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Online GDScript compiler