Interfaces
An interface enforces that a class implements a set list of public fields and methods.
Each class, by default, defines its own interface composed of public fields and methods. Dart has the ability to implement several interfaces. The keyword implements allows a class to adhere to multiple interfaces and increase an object’s polymorphic range.
The keyword implement is followed by an existing named class whose public fields then become implementation requirements for the current class. Let’s reuse the code from Example 4.21 and have the Finch class implement the abstract class Being as an interface.
You decide that you want your feathered friends to have the same rights as their human counterparts. You’re going to use the Being class from Example 4.19 as an interface for class Finch. The Being class has an object surface area with one abstract method, named exist(). The Finch class is already inheriting from class Bird.
To make Finch a Being, you’re going to implement the Being interface in Example 4.22.
EXAMPLE 4.22
abstract class Being
{
Being()
{
print('-- Init Being--');
}
void exist();
}
abstract class Vertebrate extends Object
{
Vertebrate(String action)
{
print('Vertebrate is: $action');
}
}
abstract class Bird extends Vertebrate
{
Bird(String action):super('Spined')
{
print('Bird is: $action');
}
}
class Finch extends Bird implements Being
{
String color;
Finch(this.color):super('Winged')
{
print('Finch is : ' + this.color.toString() );
}
void exist()
{
print('--I am a $color Finch--');
}
}
main() {
Being aBeing = new Finch("yellow");
aBeing.exist(); //prints --I am a Yellow Finch--
Bird aBird = new Finch("Yellow");
aBeing = aBird as Being;
aBeing.exist(); //prints --I am a Yellow Finch--
print( aBird is Bird ); //prints true
print( aBird is Finch ); //prints true
print( aBird is Vertebrate ); //prints true
print( aBird is Being ); //prints true
}
An interface does not share behavior and defines only available fields and methods. If you do not implement the fields required from the interface, you will receive an error.
Let’s see what happens if the class Being changes to a concrete implementation (Example 4.23), while leaving it as the interface for class Finch.
EXAMPLE 4.23
class Being extends Object
{
Being()
{
print('-- Init Being--');
}
void exist() {
print('--I am Being and I exist--');
}
}
main() {
Being aBeing = new Finch("yellow");
aBeing.exist(); //still prints --I am a Yellow Finch--
}
Even if you change class Being to a concrete class, with a concrete implementation of exists(), the change will have no effect on the classes that implement its interface. Again, interfaces do not share behavior; they only enforce available fields.