pony/subtypes/main.pony

60 lines
1.8 KiB
Pony

// There are two kinds of subtyping
// This is nominal subtyping
// This is a lot like what Java does with classes and interfaces
// First, define a trait
trait Named
// This is the default implementation of name()
fun name(): String => "Bob"
// Now, define a class that has that trait, using the `is` keyword
class Bob is Named
// The class Bob provides Named (or, more laconically, Bob is Named)
// If Bob doesn't provide a definition for name(), it will inherit the default
// implementation from Named
trait Bald
fun hair(): Bool => false
// A class can provide more than one trait
class Alice is (Named & Bald)
// All Funky classes are also Named, automatically
trait Funky is Named
fun funk_it(): I32 => 111
// This class is Funky and Named
class Charlie is Funky
// Doreen does not provide Named, even though it matches the interface.
// This is because traits are nominal: a class provides a trait only if
// it *says* it does.
class Doreen
fun name(): String => "Doreen"
// A concrete type is a member of a structural category if it has all the needed
// elements, no matter what it happens to be called.
interface HasName
fun name(): String
// All the classes above that implement name() or inherit an implementation (Bob,
// Alice, Charlie and Doreen) provide HasName. Even if the writer(s) of those
// classes did not intend it or are aware of it at all.
// Pony interfaces can have functions with default implementations, just like Pony
// traits. But a type will only be able to use those if they are declared as
// implementing the interface with the `is` keyword.
interface Excellent
fun nice(): String => "party time!"
class Edward is Excellent
let _priv: I32
new create(nothing: String) =>
_priv = 12
actor Main
new create(env: Env) =>
let ed = Edward("Pointless")
env.out.print(ed.nice())