A Deep Dive into more O.O.P. concepts in Dart

Factory Methods

Factory methods are static methods that return an instance of the class. They are often used as constructors.

An example of how a factory method works is

class Employee {
  int _id;

  String _name;

  double _salary;

  Employee(this._id, this._name, this._salary);

  factory Employee.fromJson(Map<String, dynamic> json) {
    return new Employee(json['id'], json['name'], json['salary']);
  }
}

In this example, the fromJson() method is a factory method that creates an Employee instance from a JSON object.

Singleton

A singleton is a class that can have only one instance at a time. When you try to create a new instance of a singleton, it returns the existing instance.

An example of how a singleton works is

class Logger {
  static final Logger _instance = new Logger._internal();

  factory Logger() {
    return _instance;
  }

  Logger._internal();
}

In this example, the _instance variable is the only instance of the Logger class. When you try to create a new instance of the Logger class, it returns the _instance variable.

Abstract Classes

An abstract class is a class that cannot be instantiated. It can only be inherited by other classes. Abstract classes are often used to provide an interface for a group of related classes.

Let us see an example of an abstract class:

abstract class Animal {
  void breathe();

  void eat();
}

In this example, the Animal class is an abstract class. It has two methods, breathe() and eat(). These methods must be implemented by any class that inherits from Animal.

Interfaces

An interface is a contract that defines how a class must behave. A class that implements an interface must provide implementations for all of the interface's methods.

Let us see an example of an interface:

interface Vehicle {

void drive();

void turn();

}

In this example, the Vehicle interface has two methods, drive() and turn(). Any class that implements the Vehicle interface must provide implementations for these methods.

Enums

An enum is a type that represents a set of values. Enums are often used to define a set of constants.

Let us see an example of an enum

enum Color {
  red,

  green,

  blue
}

In this example, the Color enum represents the colors red, green, and blue.

Generics

Generics allow you to define a type that can be used with any other type.

Generics are often used to create type-safe collections.

Let us see an example of generics

List<int> numbers = [1, 2, 3, 4, 5];

In this example, the List type represents a list of integers. This type can only be used with lists of integers.

Extensions

Extensions allow you to add new methods to existing classes. Extensions are often used to add utility methods to existing classes.

Let us see an example of an extension

extension on String {
  String repeat(int times) {
    return new List.filled(times, this).join();
  }
}

In this example, the extension on String adds a new method, repeat(), to the String class. This method repeats a string a given number of times.

Syntactic Sugar

Syntactic sugar is a feature that makes a language easier to read and write. It does not add any new functionality to the language.

Dart has several features that can be considered syntactic sugar. For example, Dart allows you to define a class with a shorthand syntax:

class Point {
  int x;

  int y;
}

This is equivalent to the following:

class Point {
  int x;

  int y;

  Point(this.x, this.y);
}

Mixins

Mixins allow you to reuse code between multiple classes. Mixins are often used to

define small pieces of functionality that can be added to multiple classes.

Let us see an example of a mixin

mixin Animal {
  void breathe() {
    print("breathe");
  }

  void eat() {
    print("eat");
  }
}

In this example, the Animal mixin defines two methods, breathe() and eat(). These methods can be added to any class.

Libraries

A library is a collection of code that can be imported and used in other Dart programs. Libraries can contain classes, functions, and variables.

Dart comes with a standard library that contains a large number of useful utilities and classes.

Let us see an example of how to use a library

import 'dart:io';

void main() {

stdout.write("Enter your name: ");

String? name = stdin.readLineSync();

print("Hello, $name ! Welcome to Dart.");



}

In this example, the

dart:io

library is imported. This library contains a number of useful classes and functions for input/output.

Utilities

Dart utilities are special methods that are called automatically when certain events occur.

The most common type of utility is the tear-off. A tear-off is a method that is called when an object is destroyed.

Async/await

Async and await are keywords that can be used to run code asynchronously.

Let us see an example of async/await

import 'dart:io';

main() async {
  for (int i = 0; i < 5; i++) {
    await Future.delayed(Duration(seconds: 1));

    print(i);
  }

  stdout.write("Done!");
}

In this example, the main() method uses the await keyword.

This keyword tells the program to wait for a Future to complete before continuing. The main() method delays for one second and then prints a number. This process repeats five times. After the program is done, it prints the word "Done!".

Conclusion

Thank you for going through these concepts. Now you are equipped to write amazing Dart programs.