Classes in Dart

Object Class

Dart is an object-oriented language. Everything in dart are Objects. Object is a base class for all Dart Objects. All objects inherit from the Object class

Every object is an instance of a class.

What is class

The class is to extend code for creating objects, providing initial values for state (member variables) and implementations of behavior (member methods).

Dart is an object-oriented language. In Dart, every object is an instance of a class, and all classes descend from Object.

Except Object class, every class has a single superclass.

A class has constructors, instance members and static members.

Classes defined by class declarations:

The following code snippet shows how to declare a class using class keyword.

// Person class
class Person {

}

Instance Variable

The instance variable is to make it accessible within methods and constructor of class and accessible outside of its class(another class) by creating instance of class.

OR:

Instance variables are created when an object is instantiated, and are accessible to all the methods, the constructor and block in the class.

All uninitialized instance variables have the value null. All instance variables generate an implicit getter and setter method.

Note: If you initialize an instance variable where it is declared, the value is set when the instance is created, which is before execution of the constructor and its initializer list.

Declare instance variable within a class declaration:

The following code snippet shows how to declare a instance variables.

class Person {
  // Declare instance variable firstName, initially null
  String firstName;

  // Declare instance variable lastName, initially null
  String lastName;

  // Declare instance variable age, initially 0
  int age = 0;
}

Access instance variable:

  1. Create an new instance of a person class.
  2. Use a member access operator dot (.) to access the instance variable.
  3. Implicitly instance variable has setter method, set the value to instance variable.
  4. Implicitly instance variable has getter method, get the value of instance variable.

The following code snippet shows how access instance variables.

main() {
  // Create an instance of a person class
  var person = Person();

  // Use a dot (`.`) to refer to an instance variable.
  // // Use the setter method to Set the firstName value
  person.firstName = 'Rock';

  // Use the getter method to get the firstName value
  // print to console
  print(person.firstName);

  //print Values default to null.
  print(person.lastName);

  // Use the getter method to get the age value
  // print to console
  print(person.age);
}

Instance Methods

The instance methods is to provide behavior for an object and make it accessible within methods and constructor of class and accessible outside of its class(another class) by creating instance of class.

Instance methods on objects can access instance variables and this.

Declare Instance Methods within the class declaration:

The following code snippet shows how to declare a instance methods.

class Person {

  // Declare a method with firstName and lastName as parameters
  void displayFullName(firstName, lastName) {
    // print fullName to the console
    print('$firstName $lastName');
  }

}

invoke a instance method:

To invoke a instance method, we have to create an Object of the class:

  1. Create an new instance of a person class.
  2. Use a member access operator dot (.) to access the instance method.

The following code snippet shows how to invoke instance methods.

main() {
  //Create an instance of the class
  var person = Person();

  // Use a dot (`.`) to refer to an instance method.
  person.displayFullName('Rock', 'Star');
}

Getter method

The getter function is to retrieve or read the value of object property and also use whenever you need more control over a property than a simple field allows.

Getters are implicit class member functions.

If no return type is specified, the return type of the getter is dynamic.

A getter function consists of an type, identifier, function's name, body with return type and the signature is empty.

<type> get<identifier> <functionName> <{}>body with return keyword.

The following code snippet shows how to define getter with arrow syntax and function syntax.

double _discount = 5.0;

  // Arrow syntax
  double get Discount => _discount;

  // OR
  double _discount = 5.0;

  double get Discount {
    return _discount;
  }

The example shows how to access the getter function by creating instance of its class.

class Product {
  double _discount = 5.0;

  double get Discount {
    return _discount;
  }
}

main() {
  var p = Product();
  print(p.Discount);
}

Setter method

The setter function is to set or write the value to the object property and also use whenever you need more control over a property than a simple field allows.

Setters are implicit class member functions.

If no return type is specified, the return type of the setter is void.

A setter function consists of an identifier, function's name. The function name is followed by a signature and body.

set<identifier> <functionName> signature<()> body<{}>

The following code snippet shows how to define setter function

set Discount(double value) {
    if (value >= 0) {
      _discount = _discount + value;
    }
  }

This example shows access setter function by creating instance of its class.

  1. Create an instance to the person object
  2. Use Member access operator dot(.) to access the setter method
class Product {
  double _discount = 5.0;

  double get Discount {
    return _discount;
  }

  // Setter
  set Discount(double value) {
    if (value >= 0) {
      _discount = _discount + value;
    }
  }
}

main() {
  var p = Product();

  // Use dot operator access and set the value via access setter method
  p.Discount = 5.0;

  print(p.Discount); // 10.0
}

What is abstract class?

The abstract class is to make a class that can’t be instantiated and must be extended by subclass.

It can contain class members and static methods.

OR:

An abstract class is a class that is explicitly declared with the abstract modifier.

An abstract class:

  1. That can’t be instantiated.
  2. Must be extended.
  3. Use the abstract modifier.
  4. Can contain class members.

When abstract class are useful?

The Abstract class contains common code, thereby reducing code duplication.

Abstract classes are useful for defining interfaces, often with some implementation.

If Class Person is intended to be abstract.

  • warn about any attempt to instantiate Person.
  • No complain about unimplemented methods in Person

Use the abstract modifier while declaring abstract class:

The following code snippet shows how to declare abstract class and extended by subclass.

abstract class Person {
  String name;
  bool isEmployee;

  Person(this.name, this.isEmployee);
}

// Extend class
class Employee extends Person {
  Employee(String name, bool isEmployee) : super(name, isEmployee);
}

main() {
  // Abstract classes can't be instantiated.
  var person = Person('Rock star', true); // compile time error

  var employee = Employee('Rock Star', true); // ok
}

What is Abstract Method?

The abstract method is to define a method without implementation and without a body in a abstract class.

An abstract method:

  1. Does not provide implementation.
  2. has no method body.
  3. It can only exist in abstract classes.

Abstract methods are useful when developing an abstract class that relies on a method where a default implementation is not appropriate.

Instance, getter, and setter methods can be abstract, defining an interface but leaving its implementation up to other classes.

To make a method abstract, use a semicolon (;) instead of a method body:

abstract class Person {

  // Abstract method
  String fullName(String name);
}

The following example, shows Employee class extends the Person abstract class and implement abstract method.

// Abstract class
abstract class Person {
  String name;
  bool isEmployee;

  Person(this.name, this.isEmployee);

  // Abstract method
  String fullName();
}

class Employee extends Person {
  Employee(String name) : super(name, true);

  // provide own implementation logic
  String fullName() {
    return 'Mr. ${this.name}';
  }
}

main() {
  var employee = Employee('Rock star');

  var name = employee.fullName();

  print(name); // Mr. Rock star
}

Compile time error

Classes that extends from a class with an abstract method must implement that method, otherwise the code will not compile.

abstract class Person {

  // Abstract method
  String fullName(String name);
}

// Missing concrete implementation of 'Person.fullName'.
// Try implementing the missing method
class Employee extends Person {}

Static variables

Use the static keyword to implement class-wide variables and methods.

Static variables (class variables) are useful for class-wide state and constants. A static variable is a variable that is not associated with a particular instance, but rather with an entire library or class. Static variables include library variables and class variables

OR:

The static variable is a state shares the value of it among all instances of the class. Static variables is also know as class variables.

In Dart we can declare a static variables in three ways.

  1. Static variable
  2. Static final class variable
  3. Static constant class variable

Static variables include library variables and class variables.

Note: Statice variables must be declared using the keywords const, final, var or a type name.

Declare static variable

Static class variables must be declared using the keywords const, final, var or a type name.

Static final variable

Declare a variable inside the class. To make it static, use static keyword while declaring

The following code snippet show how to declare a static variable and access the value.

class Product {
  static double defaultDiscount = 5.0;
}

main() {
  Product.defaultDiscount; // 5.0
  print(Product.defaultDiscount);
}

Note: Static variables aren’t initialized until they’re used.

Static constant variable

Declare a variable inside the class. To make it static final, use static keyword before final modifier while declaring.

The following code snippet shows how to declare a static final variable.

class Product {
  static final defaultDiscount = 5.0;
}

Declare a variable inside the class. To make it static const, use static keyword before const modifier while declaring.

Note: Only static fields can be declared as const.

The following code snippet shows how to declare static constant variables.

class Product {
  static const defaultDiscount = 5.0;
}

Static Methods

Static methods (class methods) do not operate on an instance, and thus do not have access to this.

The following code snippet shows how to declare a static method and invoke by class definition.

class Product {
  static double defaultDiscount(double discount) {
    return discount + 5.0;
  }
}

main() {
  print(Product.defaultDiscount(5.0));
}

Extending a class

You extend a class when you want the new class to have all the same features of the original, and something more. The child class may then either add new functionalities, or override some functionalities of the parent class

Use extends to create a subclass, and use super to refer to the superclass

The following code snippet shows how to extend a class using extend keyword.

class Customer {
  double Discount() {
    return 5.0;
  }
}

class RetailCustomer extends Customer {
  double Discount() {
    return 5.0 + super.Discount();
  }
}

main() {
  var retailCustomer = RetailCustomer();
  retailCustomer.Discount(); // 10.0
}

Private Members

Unlike Java, Dart doesn’t have the keywords public, protected, and private. If an identifier starts with an underscore (_), it’s private to its library.

A leading underscore character ( _ ) indicates that a member is private to its library.

The following code snows how to declare a private members.

class Person {
// Visible only in this library.
  final _firstName;

  final _lastName;

  Person(this._firstName, this._lastName);
}

Implicit Interface

Every class implicitly defines an interface containing all the instance members of the class and of any interfaces it implements.

If you want to create a class Manager that supports class Person’s API without inheriting Person’s implementation, class Manager should implement the Person interface.

A class implements one or more interfaces by declaring them in an implements clause and then providing the APIs required by the interfaces.

The following code snippet shows how to implement implicit interface.

// A person. The implicit interface contains fullName().
class Person {
// In the interface, but visible only in this library.
  final _firstName;

  final _lastName;

  // Not in the interface, since this is a constructor.
  Person(this._firstName, this._lastName);

// In the interface.
  String fullName() => '$_firstName $_lastName';
}

// An implementation of the Person interface.
class Employee implements Person {
  get _firstName => '';
  get _lastName => '';

  String fullName() => '$_firstName $_lastName';
}

String getName(Person person) => person.fullName();

void main() {

  print(getName(Person('Rock', 'Star')));

  print(getName(Employee()));
}