Dart Programming Language

Dart Programming Language

hope you learn something new here ;)

ยท

12 min read

Heyy fellow techies!!!

Presuming you're already having some idea about Java or C++, I'd like to introduce Dart to you.

It's actually very easy if you have done any object oriented language before but even if you're a beginner, feel free to go through the blog as I have made things simple.

There are no restrictions.

I have covered almost everything I guess. But even if I missed something you can reach out to me and inform me.

That'd be of some great help.

I have prioritised more on the code part because it makes easier to understand stuff.

So let's get started!!!

Dart was developed by Google. It is a scalable language (i.e. used to write large programs) and is used all over the world for building applications and is used in the most popular frontend framework i.e. Flutter. Be it mobile, web or server-side applications and command line scripts. With the help of dart, it is quite easy to do such things.

Note: Go through the code sample properly if you wanna learn with full efficiency. It contains important definitions which need to be properly understood by you.

Syntax

void main(){
    print("Hi");
    print('Hi');
    // this is a comment
    // ends with semicolon
}

Output: Hi
        Hi
        (both are the same)

Data Types

All data types in Dart are objects. Therefore their initial value is defined as null.

(int, double, Strings, boolean, Lists, Maps, Runes, Symbols)

int a = 1; 
var a = 2;

double d = 3.3;
var d = 3.4;

String s = "abc";
var s = "xyz";

bool b = true;
var b = false; 

// var automatically reads value and determines which data type you're using.

Literals

We can assign literals to some variables eg. int x = 2.

int = datatype, x = variable, 2 = Literal. (could be Strings, double etc)

Escape Character ('\')

String s = 'It\'s easy'

(makes it recognizable because it's confusing)

String Interpolation('$')

// We use '+' in Java and C++ to add something in print statements.
// In Dart, we use $

String s1 = "Sanzu";
String s2 = "Name: $s1";
String s3 = "${s1.length}"

Final and Static keyword

final: As the name suggests, when you initialize a value add final to it so that you can't change it afterwards. (means it's the final value of that variable and it's value can't be changed afterwards on further lines of code)

const: It's just like final, but is compiled during compilation.

Conditional Statements:

i) If-Else

if(condition){
      //code
} else {
      //code
}

ii) If Else-If (multiple conditions)

if(condition 1){
      //code
} else if (condition 2){
      //code
} else if (condition 3){
      //code
} else {
      //code
}

iii) Switch case (only works for int and String)

String grade = 'A';
    switch (grade){
        case 'A':
            print("Excellent");
            break;

        case 'B':
            print("Very Good");
            break;

        case 'C':
            print("Good enough. But work hard");
            break;

        case 'D':
            print("You barely pass");
            break;

        case 'E':
            print("You have failed");
            break;

        default:
            print("Enter a valid Grade");
    }
}

Loops:

i) for

for (int i = 1; i <= 10; i++) {
        if ( i % 2 == 0) {
            print(i);
        }
}

ii) for in

List expressions = ["hello", "hi", "bye"];
    for (String s in expressions) {
        print(s);
    }
}

iii) Nested for

for (int i=1; i <= 10; i++) {
   for (int j=1; j <= 10; j++) { 
        // any condition
   }
}

iv) while

int i = 1;
    while (i <= 10) {
        if (i % 2 == 0) {
            print(i);
        }
        i++;
    }

v) do while

int i = 1;
    do {
        if ( i % 2 == 0) {
            print(i);
        }
        i++;
    } while ( i <= 10);

Break and Continue

We use this to break outside our loop. In flutter, we have a special functionality which is: we can break any loop just by calling it.

myOuterLoop: for (int i = 1; i <= 3; i++) {
    innerLoop: for (int j = 1; j <= 3; j++) {
        print("$i $j");
        if (i == 2 && j == 2) {
            break myOuterLoop;
        }
    }
}

// continue - the loop skips the condition where continue is there and the         further the iteration is continued.

Functions

void main() {
    findPerimeter(4, 2);
    int rectangleArea = getArea(10, 5);
    print("The area is $rectangleArea");
}

void findPerimeter(int l, int b) {
    print(2*(l+b));
}

int getArea(int l, int b) {
    return l*b;
}

// function - main() - 0 arguments
//            findPerimeter(int l, int b) - 2 arguments 
//            getArea(int l, int b) - 2 arguments
// arguments are something that we pass after a function
// just see and code and try to figure out how are we passing the values, data types and arguments.

Fat Arrow ('=>')

void main() {
    print('hi'):
}
// can also be written as
void main() => print('hi');

Exception Handling

An exception is an error that takes place inside the program. When an exception occurs inside a program the normal flow of the program is disrupted and it terminates.

Many expections can be passed using clauses.

// 1. ON Clause
// 2. Catch Clause with Exception Object
// 3. Catch Clause with Exception Object and StackTrace Object
// 4. Finally Clause
// 5. Create our own Custom Exception

void main() {
    // CASE 1: When you know the exception to be thrown, use ON Clause
    try {
        int result = 12 ~/ 0;
        print("The result is $result");
    } on IntegerDivisionByZeroException {
        print("Cannot divide by Zero");
    }

    // CASE 2: When you do not know the exception use CATCH Clause
    try {
        int result = 12 ~/ 0;
        print("The result is $result");
    } catch (e) {
        print("The exception thrown is $e");
    }

    // CASE 3: Using STACK TRACE to know the events occurred before Exception was thrown
    try {
        int result = 12 ~/ 0;
        print("The result is $result");
    } catch (e, s) {
        print("The exception thrown is $e");
        print("STACK TRACE \n $s");
    }

    // CASE 4: Whether there is an Exception or not, FINALLY clause is always executed
    try {
        int result = 12 ~/ 3;
        print("The result is $result");
    } catch (e) {
        print("The exception thrown is $e");
    } finally {
        print("This is FINALLY Clause and is always executed.");
    }

    // CASE 5: Custom Exception
    try {
        depositMoney(-200);
    } catch (e) {
        print(e.errorMessage());
    } finally {
        // Code
    }
}

Class, Objects and Reference variables

void main() {

    var student1 = Student(); // One Object, student1 is reference variable
    student1.id = 23;
    student1.name = "Peter";
    print("${student1.id} and ${student1.name}");

    student1.study();
    student1.sleep();

}

class Student {
    int id = -1;             // Instance or Field Variable, default value is -1
    String name;          // Instance or Field Variable, default value is null

    void study() {
        print("${this.name} is now studying");
    }

    void sleep() {
        print("${this.name} is now sleeping");
    }
}

Constructors

void main() {

    var student1 = Student(23, "Peter");// One obj, student1 is reference var
    print("${student1.id} and ${student1.name}");

    student1.study();
    student1.sleep();
}

class Student {
    int id = -1;
    String name;

    Student(this.id, this.name);    // Parameterised Constructor

    Student.myAnotherNamedConstructor(this.id, this.name);  // Named Constructor

    void study() {
        print("${this.name} is now studying");
    }

    void sleep() {
        print("${this.name} is now sleeping");
    }
}

Getters and Setters

void main() {

  var student = Student();
  student.name = "Peter";     // set value
  print(student.name);        // get value

  student.percentage = 438.0;   // set value
  print(student.percentage);    // get value
}

class Student {
  String name;       
  double percent;    
  void set percentage(double marksSecured) => percent = (marksSecured / 500) * 100;
  double get percentage => percent;
}

Inheritance

Process of getting properties of another class.

void main() {

    var dog = Dog();
    dog.breed = "Labrador";
    dog.color = "Black";
    dog.bark();
    dog.eat();

    var cat = Cat();
    cat.color = "White";
    cat.age = 6;
    cat.eat();
    cat.meow();

    var animal = Animal();
    animal.color = "brown";
    animal.eat();
}

class Animal {
    String color;
    void eat() {
        print("Eat !");
    }
}

class Dog extends Animal {      // Dog is Child class or sub class, Animal is                            super or parent class
    String breed;
    void bark() {
        print("Bark !");
    }
}

class Cat extends Animal {      // Cat is Child class or sub class, Animal is super or parent class
    int age;
    void meow() {
        print("Meow !");
    }
}

Method Overriding

Allows a method in a child class to override the same method in the parent class. In

void main() {

    var dog = Dog();
    dog.eat();

    print(dog.color);Animal = parent class.                    Dog = child class

Abstraction

the class which contain one or more than 1 abstract method

void main() {

//    var shape = Shape();        // Error. Cannot instantiate Abstract Class

    var rectangle = Rectangle();
    rectangle.draw();

    var circle = Circle();
    circle.draw();
}

abstract class Shape {

    // Define your Instance variable if needed
    int x;
    int y;
    void draw();        // Abstract Method
    void myNormalFunction() {
        // Some code
    }
}

class Rectangle extends Shape {
    void draw() {
        print("Drawing Rectangle.....");
    }
}

class Circle extends Shape {
    void draw() {
        print("Drawing Circle.....");
    }
}

Interface

Simply pointing out similarities among unrelated class.

void main() {

    var tv = Television();
    tv.volumeUp();
    tv.volumeDown();
}

class Remote {

    void volumeUp() {
        print("______Volume Up from Remote_______");
    }

    void volumeDown() {
        print("______Volume Down from Remote_______");
    }
}

// Here Remote acts as Interface
class Television implements Remote, AnotherClass {

    void volumeUp() {
//        super.volumeUp();       // Not allowed to call super while implementing a class as Interface
        print("______Volume Up in Television_______");
    }

    void volumeDown() {
        print("______Volume Down in Television_______");
    }

    void justAnotherMethod() {
        print("Some code");
    }
}

Static Methods

It is used for method that is the same for every instance of a class, this means if a data type is static, it can be accessed without creating an object.

void main() {

    var circle1 = Circle();
//    circle1.pi;     // 4 bytes

    var circle2 = Circle();
//    circle2.pi;     // 4 bytes

    // 8 bytes      // waste of extra 4 bytes

    Circle.pi;  // 4 bytes
    Circle.pi;  // No more memory will be allocated .


//    circle.calculateArea();

//    print(Circle.pi);           // Syntax to call Static Variable

//    Circle.calculateArea();     // Syntax to call Static Method
}

class Circle {

    static const double pi = 3.14;
    static int maxRadius = 5;

    String color;

    static void calculateArea() {
        print("Some code to calculate area of Circle");
//        myNormalFunction();     // Not allowed to call instance functions
//        this.color;             // You cannot use 'this' keyword and even cannot access Instance variables
    }

    void myNormalFunction() {
        calculateArea();
        this.color = "Red";
        print(pi);
        print(maxRadius);
    }
}

Lambda Expressions aka Arrow Functions

void main() {

    // Defining Lambda: 1st way
    Function addTwoNumbers = (int a, int b) {
        var sum = a + b;
        print(sum);
    };

    var multiplyByFour = (int number) {
        return number * 4;
    };

    // Defining Lambda: 2nd way: Function Expression: Using Short Hand Syntax or FAT Arrow ( '=>' )
    Function addNumbers = (int a, int b) => print(a + b);

    var multiplyFour = (int number) => number * 4;


    // Calling lambda function
    addTwoNumbers(2, 5);
    print(multiplyByFour(5));

    addNumbers(3, 7);
    print(multiplyFour(10));
}


// A example of Normal function
void addMyNumbers(int a, int b) {

    var sum = a + b;
    print(sum);
}

Lexical Closure

A closure is a function that has access to the parent scope, even after the scope has closed.

A closure is a function object that has access to variables in its lexical scope, even when the function is used outside of it's original scope.

void main() {

    String message = "Dar is good";

    Function showMessage = () {
        message = "Dart is awesome";
        print(message);
    };

    showMessage();

    Function talk = () {
        String msg = "Hi";
        Function say = () {
            msg = "Hello";
            print(msg);
        };
        return say;
    };
    Function speak = talk();
    speak();        // talk()     // say()      //  print(msg)    // "Hello"
}

Bunch of remaining data types:

Lists

i) fixed

void main() {
    List<int> numbersList = List(5);        // Fixed-length list
    numbersList[0] = 73;  // Insert operation
    numbersList[1] = 64;
    numbersList[3] = 21;
    numbersList[4] = 12;

    numbersList[0] = 99;  // Update operation
    numbersList[1] = null;// Delete operation

    print(numbersList[0]);
    print("\n");

//    numbersList.remove(73);                 // Not supported in fixed-length list
//    numbersList.add(24);                    // Not supported in fixed-length list
//    numbersList.removeAt(3);                // Not supported in fixed-length list
//    numbersList.clear();                    // Not supported in fixed-length list

    for (int element in numbersList) {                          // Using Individual Element (Objects)
        print(element);
    }

    print("\n");

    numbersList.forEach((element) => print(element));           // Using Lambda

    print("\n");

    for (int i = 0; i < numbersList.length; i++) {              // Using Index
        print(numbersList[i]);
    }
}

ii) growable

void main() {
    // Elements:    N   21  12
    // Index:       0   1   2

    List<String> countries = ["USA", "INDIA", "CHINA"];     // Growable List : METHOD 1
    countries.add("Nepal");
    countries.add("Japan");


    List<int> numbersList = List();                         // Growable List: METHOD 2
    numbersList.add(73);    // Insert Operation
    numbersList.add(64);
    numbersList.add(21);
    numbersList.add(12);

    numbersList[0] = 99;    // Update operation
    numbersList[1] = null;  // Delete operation

    print(numbersList[0]);

    numbersList.remove(99);
    numbersList.add(24);
    numbersList.removeAt(3);
//    numbersList.clear();

    print("\n");

    for (int element in numbersList) {                  // Using Individual Element ( Objects )
        print(element);
    }

    print("\n");

    numbersList.forEach((element) => print(element));   // Using Lambda

    print("\n");

    for (int i = 0; i < numbersList.length; i++) {      // Using Index
        print(numbersList[i]);
    }

}

Map and HashMap

void main() {

    Map<String, int> countryDialingCode = {         // Method 1: Using Literal 
        "USA": 1,
        "INDIA": 91,
        "PAKISTAN": 92
    };


    Map<String, String> fruits = Map();             // Method 2: Using Constructor
    fruits["apple"] = "red";
    fruits["banana"] = "yellow";
    fruits["guava"]  = "green";

    fruits.containsKey("apple");                        // returns true if the KEY is present in Map
    fruits.update("apple", (value) => "green");         // Update the VALUE for the given KEY
    fruits.remove("apple");                             // removes KEY and it's VALUE and returns the VALUE
    fruits.isEmpty;                                     // returns true if the Map is empty
    fruits.length;                                      // returns number of elements in Map
//    fruits.clear();                                     // Deletes all elements

    print(fruits["apple"]);

    print("\n");

    for (String key in fruits.keys) {           // Print all keys
        print(key);
    }

    print("\n");

    for (String value in fruits.values) {           // Print all values
        print(value);
    }

    print("\n");

    fruits.forEach((key, value) => print("key: $key and value: $value"));   // Using Lambda

Set and HashSet

void main() {

    Set<String> countries = Set.from(["USA", "INDIA", "CHINA"]);     // Method 1: From a list
    countries.add("Nepal");
    countries.add("Japan");


    Set<int> numbersSet = Set();                                   // Method 2: Using Constructor
    numbersSet.add(73);     // Insert Operation
    numbersSet.add(64);
    numbersSet.add(21);
    numbersSet.add(12);

    numbersSet.add(73);     // Duplicate entries are ignored
    numbersSet.add(73);     // Ignored

    numbersSet.contains(73);        // returns true if the element is found in set
    numbersSet.remove(64);          // returns true if the element was found and deleted
    numbersSet.isEmpty;             // returns true if the Set is empty
    numbersSet.length;              // returns number of elements in Set
//    numbersSet.clear();             // Deletes all elements

    print("\n");

    for (int element in numbersSet) {                  // Using Individual Element ( Objects )
        print(element);
    }

    print("\n");

    numbersSet.forEach((element) => print(element));   // Using Lambda
}

Callable class

User creates callable class which allows the instance of the class to be called as a function.

void main() {

    var personOne = Person();
    var msg = personOne(25, "Peter");
    print(msg);
}

class Person {

    String call(int age, String name) {
        return "The name of the person is $name and age is $age";
    }
}

That's all folks.

Hope you had a great time learning.

Thank you very much.

ย