Frames can also be configured to store type-information in properties, and to use that information runtime when instantiating objects. For example, consider an object model for relating persons to the pets they own:

```java
interface Person extends VertexFrame {
  @Adjacency(label = "pet") Iterable<? extends Animal> getPets();
  @Adjacency(label = "pet") void addPet(Animal animal);
}

interface Animal extends VertexFrame {
}

interface Fish extends Animal {
}
```

h2. The Problem

Without any extra information Frames isn't aware of the actual types of Animal objects. If you call @person.getPets()@, all returned objects are Animal-instances. It's not possible to instantiate them as Fish, or Dog, or other sub-classes of Animal, based on runtime information. Likewise, when you call @person.addPet(aFish)@, the fact that this particular pet is actually a Fish will be lost.

h2. Frames can Store and Use Type Data

Since Frames 2.4.0 Frames has support for instantiating polymorphic types, to tackle the above problem, and make runtime decisions about what interfaces to proxy. This is done by telling Frames what the name of each type is, and in which property field that name should be stored:
# The root of your class hierarchy (in this case the Animal interface), should be annotated with a @TypeField@ annotation. That annotation contains the property-key in which type information is stored.
# Each concrete (instantiatable) sub-type should be annotated with a @TypeValue@ annotation. That annotation holds the property value that is stored in the property with the key from @TypeField@.
# A @TypedGraphModuleBuilder@ can be used to make Frames aware of these annotations.

This may lead to the following interface definitions for our Person -> Pet graph:

```java
interface Person extends VertexFrame {
  @Adjacency(label = "pet") Iterable<? extends Animal> getPets();
  @Adjacency(label = "pet") void addPet(Animal animal);
}

@TypeField("type") interface Animal extends VertexFrame {
}

interface Mammal extends Animal {}

@TypeValue("dog") interface Dog extends Mammal {}

@TypeValue("shepherd") interface Shepherd extends Dog {}

@TypeValue("cat") interface Cat extends Mammal {}

@TypeValue("fish") interface Fish extends Animal {}
```

Please note that only Animal has a @TypeField@ annotation, because it is the root of our hierarchy. You are not allowed to change the property-key used for storing type information in subtypes of Animal. Also note that both Animal and Mammal don't have @TypeValue@ annotations. This is because pets are typically subtypes of Animal/Mammal, e.g. a Cat, or a Fish. It is not forbidden to have a @TypeValue@ annotation on the same interface that holds the @TypeField@ annotation. It just doesn't make sense in this particular example. Please also note that it's perfectly valid to have TypeValue annotations on subtypes of interfaces that already have a @TypeValue@ annotation, like the Shepherd above, which is a specific type of Dog.

With these extra annotations, Frames is now able to automatically add a @type=fish@ property when storing a vertex that represents a Fish, or @type=dog@ for a Dog. Additionally, Frames may return sub-types of Animal, using the actual property value for @type@. Thus @person.getPets()@ now returns Dogs, Fishes, etc.

h2. Using TypedGraphModuleBuilder

For Frames to actually use the @TypeField@ and @TypeValue@ annotations, a FramedGraph has to know about the interfaces annotated with @TypeValue@. Since there is no efficient way in Java to get all interfaces that have a specific annotation, your code should tell a FramedGraph where to find those interfaces. For the animal hierarchy in the previous example this may be done as follows:

```java
static final FramedGraphFactory FACTORY = new FramedGraphFactory(
    new TypedGraphModuleBuilder()
        .withClass(Fish.class)
        .withClass(Cat.class)
        .withClass(Dog.class)
        .withClass(Shepherd.class)
        .build()
);
```

Please note that only the interfaces with @TypeValue@ annotations are given. Frames will detect the @TypeField@ by itself. The @FACTORY@ created this way is reusable and thread-safe once fully initialized. It can be used to create FramedGraphs as follows:

```java
FramedGraph<Graph> framedGraph = FACTORY.create(graph);
```

h2. FAQ for Polymorphic Types

*What happens when I frame an element that doesn't have a value for the property defined in TypeField?*

Frames will just instantiate the compile time supplied interface (i.e. Animal in the previous examples).

*What happens when I frame an element that has an unknown value for the property defined in TypeValue (thus a corresponding TypeValue is missing or not registered)?*

Frames will ignore the value, hence will instantiate the compile time supplied interface (i.e. Animal in the previous examples).

*What happens when I create a Frame for an interface that has a @TypeField@ in the hierarchy, but no (registered) @TypeValue@ annotation?*

No type information will be stored. Thus if you later frame that element, it will be framed as an instance of the compile time supplied interface.