# Interfaces in Types

Interfaces can be used in types: The type `{I}` is the type of all objects that implement the interface `I`.

This is called a restricted type: Only the functionality (members and functions) of the interface can be used when accessing a value of such a type.

```
// Declare an interface named `Shape`.
//
// Require implementing types to provide a field which returns the area,
// and a function which scales the shape by a given factor.
//
pub struct interface Shape {
    pub fun getArea(): Int
    pub fun scale(factor: Int)
}

// Declare a structure named `Square` the implements the `Shape` interface.
//
pub struct Square: Shape {
    // In addition to the required fields from the interface,
    // the type can also declare additional fields.
    //
    pub var length: Int

    // Provided the field `area`  which is required to conform
    // to the interface `Shape`.
    //
    // Since `area` was not declared as a constant, variable,
    // field in the interface, it can be declared.
    //
    pub fun getArea(): Int {
        return self.length * self.length
    }

    pub init(length: Int) {
        self.length = length
    }

    // Provided the implementation of the function `scale`
    // which is required to conform to the interface `Shape`.
    //
    pub fun scale(factor: Int) {
        self.length = self.length * factor
    }
}

// Declare a structure named `Rectangle` that also implements the `Shape` interface.
//
pub struct Rectangle: Shape {
    pub var width: Int
    pub var height: Int

    // Provided the field `area  which is required to conform
    // to the interface `Shape`.
    //
    pub fun getArea(): Int {
        return self.width * self.height
    }

    pub init(width: Int, height: Int) {
        self.width = width
        self.height = height
    }

    // Provided the implementation of the function `scale`
    // which is required to conform to the interface `Shape`.
    //
    pub fun scale(factor: Int) {
        self.width = self.width * factor
        self.height = self.height * factor
    }
}

// Declare a constant that has type `Shape`, which has a value that has type `Rectangle`.
//
var shape: {Shape} = Rectangle(width: 10, height: 20)
```

Values implementing an interface are assignable to variables that have the interface as their type.

```
// Assign a value of type `Square` to the variable `shape` that has type `Shape`.
//
shape = Square(length: 30)

// Invalid: cannot initialize a constant that has type `Rectangle`.
// with a value that has type `Square`.
//
let rectangle: Rectangle = Square(length: 10)
```

Fields declared in an interface can be accessed and functions declared in an interface can be called on values of a type that implements the interface.

```
// Declare a constant which has the type `Shape`.
// and is initialized with a value that has type `Rectangle`.
//
let shape: {Shape} = Rectangle(width: 2, height: 3)

// Access the field `area` declared in the interface `Shape`.
//
shape.area  // is `6`

// Call the function `scale` declared in the interface `Shape`.
//
shape.scale(factor: 3)

shape.area  // is `54`
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://max-daunarovich.gitbook.io/flow-network/introduction/interfaces/interfaces-in-types.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
