Table of Contents
Introduction to Dart
Dart is an object-oriented programming language that was created by Google in 2011. It was designed to be a general-purpose language that could be used for web, mobile, and server development.
One of the most significant features of Dart is its built-in support for both client-side and server-side programming. This means that developers can use the same language and libraries to write both the front-end and back-end code of an application, making it easier to build and maintain full-stack applications.
It also supports asynchronous programming with the use of the “async” and “await” keywords, making it well-suited for building web and mobile applications that require real-time data.
Dart also comes with a rich set of libraries, including libraries for web development, mobile development, and server-side programming. These libraries provide developers with a wide range of tools and functionalities to build complex applications quickly and efficiently.
Dart is also used as the primary programming language for developing Flutter, Google’s open-source UI development toolkit for building natively compiled applications for mobile, web, and desktop. This makes Dart a popular choice for building cross-platform mobile applications.
Installation
- Install Dart SDK from here
- Install any Editor like VsCode from here
Basics
First Dart Program
void main() {
print('Hello, World!');
}
Data Types
In Dart language, the below data types are used:
| Description | Keyword | Description |
| Numbers | int, double, num | Used to to store numerical value |
| Strings | String | Used to to store text value |
| Booleans | bool | Used to store Boolean true and false value |
| Lists | List | Used to store an ordered group of items |
| Maps | Map | Used to store a set of values as key-value pair |
| Sets | Set | Used to store unordered list of unique values of same types |
| Runes | runes | Used to store Unicode values of String |
| Null | null | It represents null value |
Operators
Operators in programming are symbols or keywords that represent a specific operation or computation to be performed on one or more operands (values, variables, or expressions). There are various types of operators in programming, such as:
- Arithmetic Operators
- Increment and Decrement Operators
- Assignment Operators
- Relational Operators
- Logical Operators
- Type Test Operators
Arithmetic Operators
| Symbol | Operator Name | Description |
|---|---|---|
+ | Addition | For adding two operands |
- | Subtraction | For subtracting two operands |
-expr | Unary Minus | For reversing the sign of the expression |
* | Multiplication | For multiplying two operands |
/ | Division | For dividing two operands and give output in double |
~/ | Integer Division | For dividing two operands and give output in integer |
% | Modulus | Remainder After Integer Division |
Increment and Decrement Operators
| Operator Symbol | Operator Name | Description |
|---|---|---|
++var | Pre Increment | Increase Value By 1. var = var + 1 Expression value is var+1 |
--var | Pre Decrement | Decrease Value By 1. var = var – 1 Expression value is var-1 |
var++ | Post Increment | Increase Value By 1. var = var + 1 Expression value is var |
var-- | Post Decrement | Decrease Value By 1. var = var – 1 Expression value is var |
Assignment Operators
| Operator Type | Description |
|---|---|
= | Assign a value to a variable |
+= | Adds a value to a variable |
-= | Reduces a value to a variable |
*= | Multiply value to a variable |
/= | Divided value by a variable |
Relational Operators
| Operator Symbol | Operator Name | Description |
|---|---|---|
> | Greater than | Used to check which operand is bigger and gives result as boolean |
< | Less than | Used to check which operand is smaller and gives result as boolean |
>= | Greater than or equal to | Used to check which operand is bigger or equal and gives result as boolean |
<= | Less than or equal to | Used to check which operand is smaller or equal and gives result as boolean |
== | Equal to | Used to check operands are equal to each other and gives result as boolean |
!= | Not equal to | Used to check operand are not equal to each other and gives result as boolean |
Logical Operators
| Operator Type | Description |
|---|---|
&& | This is ‘and’, return true if all conditions are true |
|| | This is ‘or’. Return true if one of the conditions is true |
! | This is ’not’. return false if the result is true and vice versa |
Type Test Operators
| Operator Symbol | Operator Name | Description |
|---|---|---|
is | is | Gives boolean value true if the object has a specific type |
is! | is not | Gives boolean value false if the object has a specific type |
Conditions and Loops
User Input
Functions
Collections
Null Safety
Null safety is a feature in Dart that helps developers avoid null pointer exceptions by providing stronger type checks at compile time. It was introduced in Dart 2.12, and it allows developers to write safer and more reliable code.
Null safety introduces two new types of variables: nullable and non-nullable. A nullable variable can be assigned a value or null, while a non-nullable variable can only be assigned a value.
In Dart’s null safety feature, there are two new symbols that are introduced to represent nullable and non-nullable variables. These symbols are:
?– The?symbol indicates that a variable is nullable. This symbol is placed after the type of the variable. For example,String?indicates that the variable can hold aStringvalue ornull.!– The!symbol indicates that a variable is non-nullable. This symbol is placed after the type of the variable. For example,String!indicates that the variable can only hold a non-nullStringvalue.
The below example will clear you about Null Safety.
// Nullable variable String? nullableString = "Hello World"; nullableString = null; // Valid assignment // Non-nullable variable String nonNullableString = "Hello World"; nonNullableString = null; // Invalid assignment, will generate a compile-time error
In this example, nullableString is a nullable variable that can be assigned a value or null. The ? symbol after the String type indicates that the variable is nullable. In the first assignment, nullableString is assigned the value "Hello World", which is valid. In the second assignment, nullableString is assigned null, which is also valid.
On the other hand, nonNullableString is a non-nullable variable that can only be assigned a value. It does not have the ? symbol after the String type, indicating that the variable is non-nullable. In the first assignment, nonNullableString is assigned the value "Hello World", which is valid. In the second assignment, nonNullableString is assigned null, which is not valid and will generate a compile-time error.
Late Keyword In Dart
late keyword is used to declare a variable which is non-nullable and will be initialized at a later time.
late int age;
void main() {
// assigning value to late variable
age = 30;
print(age);
}
OOP
OOP in Dart
Dart is a modern programming language that supports OOP concepts. Some of the key features of OOP in Dart are:
- Classes: Classes are the fundamental building blocks of OOP in Dart. A class can have fields (data members) and methods (functions), and it can also extend other classes to inherit their properties and behavior.
- Inheritance: In Dart, a class can inherit properties and behavior from another class using the ‘extends’ keyword. This allows for code reuse and promotes a more modular design.
- Encapsulation: Encapsulation is the practice of hiding implementation details of an object and only exposing the necessary information to other objects. In Dart, you can use the ‘getters’ and ‘setters’ to control access to class fields.
- Polymorphism: Polymorphism is the concept of treating objects of different types as if they are of the same type. In Dart, you can achieve polymorphism through inheritance and interface implementation.
- Interfaces: An interface is a contract that defines a set of methods that a class must implement. In Dart, you can define an interface using the ‘implements’ keyword.
Overall, OOP in Dart provides a powerful set of tools for creating modular, maintainable, and extensible software systems. By leveraging these concepts, developers can build software that is more robust, scalable, and easy to understand and modify over time.
Class & Object in Dart
In Dart, a class is a blueprint or template for creating objects that have properties and behavior. To define a class in Dart, you use the class keyword followed by the class name, as shown below:
class MyClass {
// class members go here
}
Inside the curly braces of the class definition, you can define properties and methods that are associated with the class. For example, you can define a class with a single property and method like this:
class Person {
String name;
void sayHello() {
print('Hello, my name is $name');
}
}
In this example, the Person class has a single property called name, which is a string, and a method called sayHello() that prints a message to the console using the name property.
To create an instance of a class, you use the new keyword followed by the class name and any constructor arguments, if necessary, like this:
var person = new Person(); person.name = 'John'; person.sayHello(); // prints "Hello, my name is John"
In this example, we create a new Person object and set its name property to “John”. We then call the sayHello() method, which prints a message to the console using the name property.
Classes in Dart can also inherit from other classes using the extends keyword. This allows you to create more specialized classes that share properties and behavior with their parent class. You can also define interfaces using the implements keyword, which allows you to specify a set of methods that a class must implement.
Constructor in Dart
In Dart, a constructor is a special method that is used to create and initialize objects of a class. The constructor has the same name as the class and can optionally take in parameters that are used to initialize the object’s properties.
There are two types of constructors in Dart: named constructors and default constructors.
A default constructor is a constructor with no parameters. If you do not define a constructor for a class, Dart provides a default constructor that takes no arguments.
A named constructor is a constructor that has a name other than the class name. Named constructors are useful when you want to provide multiple ways to create objects of a class, or when you want to create objects using different initialization logic.
A sample Code with Class, Object and Constructor is given below:
class Person {
String name;
int age;
// Default constructor
Person(this.name, this.age);
// Named constructor
Person.fromBirthYear(String name, int birthYear) {
this.name = name;
this.age = DateTime.now().year - birthYear;
}
void sayHello() {
print("Hello, my name is $name and I'm $age years old.");
}
}
void main() {
var person1 = new Person("John", 30);
var person2 = new Person.fromBirthYear("Jane", 1990);
person1.sayHello();
person2.sayHello();
}
In this example, we define a Person class with two constructors. The first constructor is a default constructor that takes in two parameters, name and age, and uses them to initialize the object’s properties.
The second constructor is a named constructor called fromBirthYear that takes in a name parameter and a birthYear parameter. This constructor uses the DateTime.now().year property to calculate the person’s age based on their birth year and sets the name and age properties accordingly.
In the main() function, we create two Person objects, one using the default constructor and the other using the named constructor. We then call the sayHello() method on each object to print a message to the console.
By using constructors in Dart, you can create objects with the appropriate initial state and behavior, which makes your code more flexible and easier to maintain.
Encapsulation In Dart
Encapsulation is one of the fundamental principles of object-oriented programming (OOP). It refers to the practice of hiding the implementation details of an object from the outside world and providing a public interface for accessing and manipulating the object’s state.
In Dart, encapsulation can be achieved by using private and public members. Private members are those that can only be accessed within the class that defines them, while public members can be accessed from outside the class.
To define a private member in Dart, you can prefix its name with an underscore (_) character. For example, consider the following Person class:
class Person {
String _name;
Person(String name) {
_name = name;
}
void sayHello() {
print("Hello, my name is $_name.");
}
}
In this example, we define a private property called _name that can only be accessed within the Person class. We also define a constructor that takes in a name parameter and sets the _name property. Finally, we define a sayHello() method that uses the _name property to print a message to the console.
By making the _name property private, we prevent external code from directly accessing or modifying it. Instead, we provide a public method (sayHello()) that can be used to access the property indirectly. This way, we can control how the property is accessed and ensure that the object’s state remains consistent.
In summary, encapsulation is an important concept in Dart that helps to improve code organization, readability, and maintainability. By hiding implementation details and providing a public interface, you can create more robust and flexible classes that can be used in a variety of contexts.
Inheritance In Dart
Inheritance is a fundamental concept in object-oriented programming (OOP) that allows you to create new classes based on existing classes. In Dart, you can create a subclass that inherits properties and methods from a superclass by using the extends keyword.
Here is an example of how to create a class hierarchy using inheritance:
class Animal {
String name;
Animal(String name) {
this.name = name;
}
void makeSound() {
print("Unknown sound");
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void makeSound() {
print("Woof!");
}
}
void main() {
var animal = new Animal("Unknown animal");
var dog = new Dog("Fido");
animal.makeSound();
dog.makeSound();
}
In this example, we define a Animal class with a name property and a makeSound() method that prints “Unknown sound” to the console. We then define a Dog subclass that extends the Animal class and overrides the makeSound() method to print “Woof!” to the console.
In the main() function, we create an Animal object and a Dog object, and call the makeSound() method on each object. When we call animal.makeSound(), the Animal class’s implementation of makeSound() is executed and “Unknown sound” is printed to the console. When we call dog.makeSound(), the Dog class’s implementation of makeSound() is executed and “Woof!” is printed to the console.
By using inheritance in Dart, you can create more specialized classes that share common functionality with other classes. This can help to improve code organization, reduce redundancy, and make your code easier to maintain.