Menu
CoddyTech

Conception d’interfaces

Fait partie de la section Programmation orientée objet du Journey GDScript de Coddy. Leçon 24 sur 65.

Une interface est une liste de méthodes qu’une classe s’engage à avoir, sans code associé. Java et C# ont un mot-clé interface ; GDScript n’en a pas. Tu construis la même chose à partir d’une classe abstraite dont toutes les méthodes sont abstraites :

# drawable.gd
@abstract
class_name Drawable
extends RefCounted

@abstract func draw() -> String
@abstract func resize(factor: int) -> void

Elle n’a pas de variables ni de corps de méthodes. Elle décrit ce qu’un élément dessinable peut faire, et chaque classe décide comment :

# banner.gd
class_name Banner
extends Drawable

var text: String
var size := 1

func _init(t: String) -> void:
	text = t

func draw() -> String:
	return "Banner '%s' at size %d" % [text, size]

func resize(factor: int) -> void:
	size *= factor

Un Circle peut également étendre Drawable, avec un radius ainsi que ses propres méthodes draw() et resize(). Le code qui utilise l’interface ne dépend que d’elle : il fonctionne donc avec toutes les classes qui étendent Drawable, y compris celles écrites ultérieurement :

func render_all(items: Array[Drawable]) -> void:
	for item in items:
		item.resize(2)
		print(item.draw())
var items: Array[Drawable] = [Banner.new("Sale"), Circle.new(3)]
render_all(items)
Banner 'Sale' at size 2
Circle with radius 6

Une classe a un parent, elle ne peut donc étendre qu’une seule interface. Lorsqu’une classe joue un second rôle, comme celui d’être enregistrée dans un fichier, étends l’interface principale et vérifie le second rôle avec has_method() :

if item.has_method("save"):
	item.save()

Gardez chaque interface petite : quelques méthodes qui relèvent d’un même rôle. Une classe qui l’étend n’écrit alors que les méthodes dont elle a besoin.

challenge icon

Défi

Facile

Créez un lecteur multimédia autour d’une interface.

  • Dans playable.gd, faites de Playable une interface : une classe abstraite avec les méthodes abstraites play() -> String et duration() -> int (en secondes).
  • Song étend Playable. play() renvoie Playing song: TITLE by ARTIST, et duration() renvoie sa durée en secondes.
  • Video étend Playable. play() renvoie Playing video: TITLE in RESOLUTIONp (par exemple in 1080p), et duration() renvoie sa durée en secondes.
  • Playlist ne connaît que Playable. play_all() affiche le résultat de play() pour chaque élément, et total_time() renvoie la somme des durées au format M:SS (secondes sur deux chiffres, par exemple 4:05).

Les constructeurs de Song et Video sont écrits. Le code fourni lit le nombre d’éléments qui suivent, puis une ligne par élément : song TITLE ARTIST SECONDS ou video TITLE RESOLUTION SECONDS. Il appelle play_all() et affiche la durée totale. Pour song Imagine Lennon 183 et video Trailer 1080 95, il affiche :

Playing song: Imagine by Lennon
Playing video: Trailer in 1080p
Total time: 4:38

Votre code va dans playable.gd, song.gd, video.gd et playlist.gd. main.gd contient le code fourni pour les entrées/sorties et ne peut pas être modifié.

Essayez vous-même

extends Node

func _ready():
	# Code d'entrée/sortie fourni : conservez-le tel quel
	var count := int(OS.read_string_from_stdin())
	var playlist := Playlist.new()
	for i in count:
		var p := OS.read_string_from_stdin().split(" ")
		if p[0] == "song":
			playlist.add(Song.new(p[1], p[2], int(p[3])))
		else:
			playlist.add(Video.new(p[1], int(p[2]), int(p[3])))
	playlist.play_all()
	print("Total time: " + playlist.total_time())
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Compilateur GDScript en ligne