1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
# Copyright (c) 2007, Enthought, Inc.
# License: BSD Style.
# --(Interfaces)----------------------------------------------------------------
"""
Interfaces
==========
In Traits 3.0, the ability to define, implement and use *interfaces* has been
added to the package.
Defining Interfaces
-------------------
Interfaces are defined by subclassing from the **Interface** class, as shown
in the example below::
from traits.api import Interface
class IName(Interface):
def get_name(self):
" Returns the name of an object. "
This same code is shown in the **IName Interface** tab of the code.
Interface classes are intended mainly as documentation of the methods and
traits that the interface defines, and should not contain any actual
implementation code, although no check is performed to enforce this currently.
Implementing Interfaces
-----------------------
A class declares that it implements one or more interfaces using the
**implements** function, which has the form::
implements(interface [, interface2, ..., interfacen])
The semantics of this function is that the class declares that it implements
each of the *interfaces* specified as an argument to **implements**.
Also, the call to **implements** must occur at class scope within the class
definition, as shown in the following example::
from traits.api import HasTraits, implements
class Person(HasTraits):
implements(IName)
...
Only a single call to **implements** should occur within a class definition.
Refer to the **Person Class** tab in the code for a complete example of using
**implements**.
Note that in the current version, traits does not check to ensure that the
class containing the **implements** function actually implements the interfaces
it says it does.
Using Interfaces
----------------
Being able to define and implement interfaces would be of little use without
the ability to *use* interfaces in your code. In traits, using an interface is
accomplished using the **Instance** trait, as shown in the following example::
from traits.api import HasTraits, Instance
class Apartment(HasTraits):
renter = Instance(IName)
Using an interface class in an **Instance** trait definition declares that the
trait only accepts values which are objects that either:
- Implement the specified interface.
- Can be adapted to an object that implements the specified interface.
Additional information on what it means to *adapt* an object to implement an
interface is presented in the next section of the tutorial.
As before, the **Instance** trait can also be used with classes that are not
interfaces, such as::
from traits.api import HasTraits, Instance
class Apartment(HasTraits):
renter = Instance(Person)
In this case, the value of the trait must be an object which is an instance of
the specified class or one of its subclasses.
"""
# --<Imports>-------------------------------------------------------------------
from __future__ import print_function
from traits.api import *
# --[IName Interface]-----------------------------------------------------------
# Define the 'IName' interface:
class IName(Interface):
def get_name(self):
""" Returns the name of an object. """
# --[Person Class]--------------------------------------------------------------
class Person(HasTraits):
implements(IName)
first_name = Str("John")
last_name = Str("Doe")
# Implementation of the 'IName' interface:
def get_name(self):
""" Returns the name of an object. """
return "%s %s" % (self.first_name, self.last_name)
# --[Apartment Class]-----------------------------------------------------------
# Define a class using an object that implements the 'IName' interface:
class Apartment(HasTraits):
renter = Instance(IName)
# --[Example*]------------------------------------------------------------------
# Create an object implementing the 'IName' interface:
william = Person(first_name="William", last_name="Adams")
# Create an apartment, and assign 'renter' an object implementing 'IName':
apt = Apartment(renter=william)
# Verify that the object works correctly:
print("Renter is:", apt.renter.get_name())
|