We create an abstract Shape. We force class that conforms to this abstraction a getArea() and name.
In order to generate instances according to json data, we implement a factory constructor called fromJson.
It takes in a JSON object, and then returns a Square, or a Circle.
Factory constructors can return instances of the subclass.
But standard constructors can ONLY return instances of the current class.
Notice that in the abstract class Shape below, we actually can return subclass Square and Circle.
shape.dart
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 |
import 'Square.dart'; import 'Circle.dart'; abstract class Shape { double getArea(); String name = ''; // use factory constructors to initialize class instances factory Shape.fromJson(Map<String, Object> json) { final type=json['type']; switch(type) { case 'square': print('its a square!'); final side = json['side']; if (side is double) { return Square(side: side); } throw UnsupportedError('invalid or missing side'); case 'circle': print('its a circle!'); final radius = json['radius']; if (radius is double) { return Circle(side: radius); } throw UnsupportedError('invalid or missing side'); default: throw UnimplementedError('shape not recognized'); } } } |
We conform to Shape by implementing name and getArea().
We then create a constructor with required param side.
Circle.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import 'shape.dart'; class Circle implements Shape { double side = 0.0; String name = 'Circle'; Circle({required double side}) { this.side = side; } // required by abstract class getArea() { return this.side * 3.14158; } } |
We conform to Shape by implementing name and getArea.
We then create a constructor by having required param side.
Square.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import 'shape.dart'; class Square implements Shape { double side = 0.0; String name; // declared as instructed by abstract Shape String getName() => name; void setName(newName) { name = newName; } // default our name as Square Square({required double side, this.name = 'Square'}) { this.side = side; this.name = name; } getArea() { return this.side * this.side; } } |
Finally, we use it like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import 'shape.dart'; void printArea(Shape shape) { print('Area of ${shape.name} is: ${shape.getArea()}'); } void main() { final shapesJson = [ { 'type':'square', 'side':10.0, }, { 'type':'circle', 'radius': 5.0, }, ]; final shapes = shapesJson.map((shapeJson) => Shape.fromJson(shapeJson)); shapes.forEach((shape) { printArea(shape); }); |