4

Go a zádrhele pri objektoch

 1 year ago
source link: https://novotnyr.github.io/scrolls/go-a-objekty/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Go, štruktúry a správanie

Objekty sú hlavne o správaní.

A to bez ohľadu na jazyk, v ktorom ich používame, čiže aj v jazyku Go.

Geometrické útvary

Zoberme si také geometrické útvary, ktorým chceme rátať plochu.

Vyrobíme teda interfejs, ktorý reprezentuje kontrakt pre akýkoľvek objekt, ktorý dokáže vyrátať svoju plochu.

Najprv štvorce

Prvým takýmto útvarom bude útvar — štvorec. Na výpočet plochy potrebujeme jediný stav: veľkosť jeho strany side.

Ak má štvorec implementovať interfejs Shaper, stačí mu dodať príslušnú metódu:

V Go neexistuje kľúčové slovo implements či dvojbodka z iných jazykov. Ak má štruktúra všetky metódy daného interfejsu, implementuje ho automaticky.

Toto je niekde nazývané „duck typing“ — ak to kváka ako kačka, a chodí ako kačka, tak je to kačka.

U nás: ak to vie zrátať plochu, tak je to interfejs Shaper.

Budeme používať metódy na prijímači, ktorý je hodnotou (receiver je typu value) a nie smerníkom (pointer).

Testovať vieme jednoducho:

Urobme funkciu, ktorá vypíše plochu útvaru na konzolu:

Testujme:

Uvidíme:

Funkcia zobrala skutočný objekt typu Square, ktorý vyhovuje interfejsu Shaper.

Slovom, štvorec kváka ako interfejs Shaper (má všetky — jednu — jeho metódu) a teda sa dá použiť na každom mieste, ktoré pracuje s interfejsom Shaper.

Kruhy

Zaveďme kruhy:

Kruh spĺňa interfejs Shaper a preto ho môžeme ho poslať do funkcie printArea.

Uvidíme:

Urobme si rez útvarov a iterujme:

Premenná shapes je typu []Shaper a obsahuje tri položky — dve sú typu Square a jednu typu Circle.

Vďaka interfejsom máme podtypy a polymorfizmus: premenná shape v cykle sa správa raz tak, raz onak.

Pomenované útvary

Zaveďme pomenované útvary.

Vyhlásme štvorec za pomenovaný útvar:

Toto síce vyzerá ako dedičnosť, ale Go ju nemá. V skutočnosti je to embedding („zapustenie“) či kompozícia, ktorá dedičnosť simuluje.

Zmeňme tvorbu štvorcov:

Vytvorme rez pomenovaných štvorcov:

Vytlačme ich mená:

Premenná square je typu Square, ale „zdedila“ premennú name od „rodičovského“ typu NamedShape. Úvodzovky sú namieste, lebo v skutočnosti štruktúra Square je zložená z typu NamedShape a pristupuje k jeho stavu rovnako ako keby ho mala sama.

Polymorfizmus

Ukážme si polymorfizmus — zaveďme funkciu pre výpis mena pomenovaného útvaru.

Skúsme teraz vypisovať mená:

Uvidíme chybu!

Takýto typ polymorfizmu v Go nefunguje. Hoci štruktúra Square „dedí“ od štruktúry NamedShape — presnejšie „je s ňou zložená“, nevieme ju použiť v metóde, ktorá berie parameter NamedSquare.

Takýto subtyping funguje len pri interfejsoch, nie pri kompozícii!

Vytvorme si teraz rez pomenovaných útvarov:

Tiež uvidíme kýbel chýb:

Obísť to môžeme interfejsom:

Pridajme pomenovanému útvaru metódu na získanie mena:

Štruktúra NamedShape bude implementovať interfejs Namer.

Upravme funkciu tak, že jej zmeníme typ z konkrétnej štruktúry na interfejs.

Toto sme v skutočnosti vylepšili na viacerých úrovniach. Funkcia na tlačenie mena nepotrebuje pomenovaný útvar, ale akúkoľvek všeobecnú vec, ktorá má meno — a toto meno je získateľné cez metódu Name().

Ak by sme si vymysleli pomenované zvieratá, vedeli by sme ich vypisovať tiež!

Vytvorme teraz rez pomenovaných vecí typu []Namer a vypíšme ho:

Toto funguje korektne, lebo využívame podtypy cez interfejsy.

Štvorec Square „dedí“ od NamedShape a keďže NamedShape implementuje Namer s metódou Name, i na štvorci môžeme volať metódu Name().

Jej implementácia je „zdedená“ od NamedShape, teda vypisuje názov štvorca.

Upravme teraz výpis mena na štruktúre Square.

Dodajme štvorcu metódu:

Týmto sme prekryli (override) metódu Name() rodičovského NamedShape a poskytli vlastnú implementáciu.

Ak spustíme výpis nanovo, uvidíme:

Pomenované kruhy

Použime aj pomenované kruhy:

Implementujme prekrytú metódu Name:

Urobme si rez pomenovaných útvarov:

Uvidíme výpis:

Kruh nemá meno, pretože …​ sme mu pri konštrukcii nepriradili meno.

Môžeme tiež vyrobiť interfejs pre pomenované veci s plochou:

Potom vieme urobiť rez pomenovaných útvarov!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK