Julia. Les premiers pas, sixième partie

1. Conception de types abstraits et de types concrets

using Dates

let # portée locale
    d = Dates.now()
    println("Daniel Hagnoul $d\n")
end
Daniel Hagnoul 2020-11-02T10:21:47.022

Conception de types abstraits

Les types abstraits sont principalement utilisés pour modéliser les données du monde réel. Par exemple un Animal peut-être le type abstrait pour un Chat ou un Chien et un Véhicule peut-être le type abstrait pour une Voiture, un Camion ou un Bus.

La possibilité de regrouper des types et de donner au groupe un nom unique permet aux programmeurs d'appliquer un code générique commun à ces types.

En Julia les types abstraits n'ont pas de propriétés, pour cette raison un type abstrait ne spécifie pas comment les données sont stockées en mémoire.

abstract type UnBien end

#=
    UnBien c'est quelque chose qui a de la valeur.
    Ce type abstrait à le super-type Any.
=#

abstract type Propriété <: UnBien end
abstract type Action <: UnBien end
abstract type Argent <: UnBien end
#=
    Vous devez installer le paquet Geodesy avant de l'utiliser.
    Lorsqu'il est installé vous pouvez le précompiler en placant
    le curseur à la fin de using Geodesy et en tapant la combinaison
    de touches : ALT + ENTER.
    L'avoir précompilé permet à Jupyter d'être plus rapide lors 
    de la première utilisation de ce paquet.
=#
using Geodesy

"""
location(p::Propriété)

Retourne la situation géographique de la propriété en utilisant la
fonction LLA() de Geodesy.

LLA doit contenir les coordonnées (latitude, longitude, altitude)

Par exemple : Geodesy.LLA(-27.468937, 153.023628, 0.0)
"""
location(p::Propriété) = error("Emplacement non défini dans le type concret")

#= 
    L'existence de cette fonction à ce niveau signifie que les sous-types 
    concret de Propriété doivent définir la fonction location.
=#

"""
walking_distance(p1::Propriété, p2::Propriété)

Retourne la distance en mètres entre deux Propriété en utilisant 
Geodesy.distance(location1, location2)
"""
function walking_distance(p1::Propriété, p2::Propriété)
    loc1 = location(p1)
    loc2 = location(p2)
    return Geodesy.distance(loc1, loc2) # distance en mètres
end
Main.##WeaveSandBox#253.walking_distance

La logique vit complètement dans les types abstraits ! Nous n'avons pas encore défini un type concret, et pourtant nous sommes en mesure de développer un code générique qui fonctionnera pour tous les sous-types concrets de Propriété.

Conception de types concrets

La raison d'avoir une hiérarchie est de créer une abstraction sur les comportements courants des types. Par exemple, les types Appartement et Maison ont le même super-type, Propriété. Ceci est intentionnel car ils représentent tous deux une sorte d'habitation physique à un certain endroit. Nous pouvons donc définir une fonction pour n'importe quelle propriété comme suit :

struct Maison <: Propriété
    latitude::Float64
    longitude::Float64
    altitude::Float64
    prix_d_achat::Float64
    estimation::Float64
end

struct Appartement <: Propriété
    latitude::Float64
    longitude::Float64
    altitude::Float64
    prix_d_achat::Float64
    estimation::Float64
end

location(m::Maison) = Geodesy.LLA(m.latitude, m.longitude, m.altitude)
location(a::Appartement) = Geodesy.LLA(a.latitude, a.longitude, a.altitude)

ma_maison = Maison(50.123465, 5.245836, 15.24, 560000.0, 847500.0)
mon_appartement = Appartement(50.125836, 5.245932, 62.75, 913450.0, 1075414.0)

println("Distance entre ma maison et mon appartement = $(round(walking_distance(ma_maison, mon_appartement), digits = 2)) mètres.")
Distance entre ma maison et mon appartement = 268.06 mètres.

Les opérateurs isa et <:

println("Argent est un sous-type de UnBien = $(Argent <: UnBien)\n")

println("ma_maison est une valeur dont le type est Propriété = $(ma_maison isa Propriété)")
Argent est un sous-type de UnBien = true

ma_maison est une valeur dont le type est Propriété = true

La principale différence entre les types abstraits et concrets est qu'un type abstrait peut avoir des sous-types alors qu'un type concret ne peut pas avoir de sous-type.

Licence Creative Commons Attribution 2.0 Belgique