Lesson 20 of 21 · 54 min · UG / professional
Inheritance, composition and _privacy
Share a reporter; put the difference in a field or a subtype. Has-a (a lab has a sensor) is often simpler than is-a. _name is a convention: please do not touch from outside.
Campus lab board
Utilisation is used ÷ seats.
You will be able to
- ✓ Share one report() across device types instead of copying the line
- ✓ Prefer has-a (a lab holds a sensor) when is-a would only add a field
- ✓ Treat _name as a convention: please do not touch from outside
Gate sensors and lab sensors both report celsius
The report line is the same; the device name differs. Share report(dev). Copy-paste of the print into six files is how one file gets “Celcius” and five do not. Inheritance on a laptop is this idea with extra syntax: a base type that knows how to report, and subtypes that fill in id and source. You do not need that syntax to practise the design.
When the difference is only a string ("gate" vs "lab"), a field is enough. When the difference is behaviour (USB vs Wi-Fi read), you will want two functions or two classes. Do not build a class tree because a diagram looked busy — build it when two callers were about to copy a formula.
Has-a is often simpler than is-a; _privacy is a please
A lab bench has a sensor: lab["sensor"]["c"]. That is composition — a record inside a record. Inheritance says a LabSensor is-a Sensor. Has-a is usually the campus default. _raw on a dict (or _raw on a laptop instance) means “implementation leftover; outside code should call report().” It is a convention, not a lock. Double underscore name-mangling on a laptop is still not security; it is a hint against accidental clashes.
Reuse the contract, not the pygame colour. report returns a string. The kiosk prints it. The log file writes it.
Laptop: subclass, composition, _privacy
class Sensor:
def __init__(self, id, c):
self.id = id
self._raw = c
def report(self):
return f"{self.id}: {self._raw} C"
class LabSensor(Sensor):
pass
lab = {"id": "BENCH-1", "sensor": LabSensor("DHT-04", 31)}
print(lab["sensor"].report())
Words that matter
- Inheritance
- A laptop feature: a type that extends another type’s behaviour.
- Composition
- A record that contains another record — has-a.
- _name
- Convention: please do not use from outside; call the public function.
Common mistakes
Avoid: Six copied report lines with six spellings of celsius.
Do this: One report(device) every screen calls.
Run it step by step
Each box is a real program. Press Run, change a number, Run again — the output must follow your code.
1. Step 1 — one reporter
Change the unit in one function. Both devices follow.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
2. Step 2 — composition plus a private field
Lab has a sensor. Outside code uses report, not _raw.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
Example program — Difference in a field, not a second reporter
kind is data. One report.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
Your turn — Shared line
report(name, c) returns a string with both the name and C. Print report("Lab", 30) so Lab and 30 appear.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
Self-assessment
Check your understanding before you mark the lesson complete.
Progress is stored in a browser cookie on this device.