# Dart Extensions Part 1: Introduction, Extending Custom Classes, Chaining Extensions

Extensions are one of the coolest features of dart. While I heard a lot about them, I never was able to grasp them properly. So in here we are going to look at 3 Tutorials that'll help us with Dart extensions

As always if you want to follow along you can find the source code here: [dart-concepts-code](https://github.com/khkred/dart-concepts-code)

### Tutorial 1: Introduction to Dart Extensions

**What are Dart Extensions?**

Dart extensions allows us to <mark>add new functionality to a class without modifying them.</mark> This feature enables us to extend the capabilities of built-in and custom classes.

**Basic Syntax:** Here's the basic syntax for creating an extension in Dart:

```dart
extension ExtensionName on Type { 
// Add methods or properties here 
}
```

**Example:**

Let's create a simple extension on the `String` class to add a method `capitalize` that capitalizes the first letter of the string.

```dart
extension StringExtensions on String {
  String capitalize() {
    if (this.isEmpty) {
      return this;
    }
    return this[0].toUpperCase() + this.substring(1);
  }
}

void main() {
  String name = "harish";
  print(name.capitalize());
}
```

So in here we got two things:

* The `StringExtensions` extension adds a new method `capitalize` to the `String` class.
    
* The `capitalize` method checks if the string is empty. Otherwise it capitalizes the first letter and concatenates it with the rest of the string.
    

You can find the above code in here: [Tutorial 1: String Extension](https://github.com/khkred/dart-concepts-code/commit/51e7db32520e65c564bdd45bb3d56beacbca578e)

### Assignment 1:

Create an extension on the `String` class that adds a method `isPalindrome` to check if the string is a palindrome.

You can find the solution in here: [Assignment-1 Solution](https://github.com/khkred/dart-concepts-code/commit/202b340ae58ae1d855f73d8ad8179e2b54aa19db)

### Tutorial 2: Extending Custom Classes

In here we are going to cover the following topics:

* Extending custom classes
    
* Using extensions to add utility methods
    
* Scope and limitations of extensions
    

**Creating a Custom Class:**

First let's add a simple `Person` with properties `name` and `age`

```dart
class Person {
  String name;
  int age;
  Person(this.name, this.age);
}
```

**Extending the Custom Class**

Now, let's write an extension to add a method `greet` that returns a greeting message including the person's name.

```dart
extension PersonsExtensions on Person {
  String greet() {
    return "Hello my name is $name and I am $age years old.";
  }
}

void main() {
  Person person = Person('Harish', 28);

  print(person.greet());
}
```

So in the above code:

* The `PersonExtensions` extension adds a new method `greet` to the `Person` class.
    
* The `greet` method constructs a greeting message using the `name` and `age` properties of the `Person` instance.
    

**Scope and Limitations of Extensions**

* **Scope**: Extensions can only add methods and getters. <mark>They cannot add instance variables or modify the internal state of the class directly</mark>.
    
* **Limitations**: <mark>Extensions do not have access to private members of the class they are extending.</mark> They can only work with public members.
    

You can find the code here: [Tutorial 2 Custom Class Extension](https://github.com/khkred/dart-concepts-code/commit/a57bce1e051a442b48d373367d04173c41fac480)

### Assignment 2:

Create a custom class `Book` with properties `title` and `author`. Write an extension to add a method `description` that returns a string describing the book with its title and author.

You can find the solution here: [Assignment 2 Solution](https://github.com/khkred/dart-concepts-code/commit/514999b2e0b7c0976aaca7f80dbfa6563029465b)

### **Tutorial 3: Chaining Extensions**

In here we are going to cover:

* Method chaining with extensions
    
* Creating fluent interfaces using extensions
    
* Examples of chaining methods
    

**Example: Chaining Methods**

Let's create an extension on the `List` class.

We'll add two methods:

* `doubleEach` (doubles each element in a list of integers)
    
* `sum` (returns the sum of all elements).
    

We will use method chaining to double the elements and then get the sum.

```dart
extension ListExtensions on List<int> {
  List<int> doubleEach() {
    for (int j in this) {
      j = j * 2;
    }

    return this;
  }

  int sum() {
    int total = 0;

    for (int value in this) {
      total += value;
    }

    return total;
  }
}

void main() {
  List<int> numbers = [1, 2, 3, 4, 5];

  int result = numbers.doubleEach().sum();

  print(result);
}
```

Perfect in here:  
The `ListExtensions` extension adds two methods to the `List<int>` class:

* `doubleEach`: Doubles each element in the list and returns the modified list.
    
* `sum`: Returns the sum of all elements in the list.
    

You can find the source code here: [Tutorial 3: List Extensions](https://github.com/khkred/dart-concepts-code/commit/f76dffdb2681f2f59e5ccede99f61e5fe398f4a4)

### Assignment 3:

Create an extension on the `String` class to add methods `reverse` (reverses the string) and `capitalizeEachWord` (capitalizes the first letter of each word). Use method chaining to reverse the string and then capitalize each word.

Solution: [Assignment 3 Solution](https://github.com/khkred/dart-concepts-code/commit/23feafe5f31b6c9e84c850d4e36f7e826bff607c)

### Next Tutorial:

In the next tutorial we'll look at

**Tutorial 4: Extensions for Collections**

* Working with collections (List, Map, Set)
    
* Adding utility methods for collections
    
* Examples of useful collection extensions
    

**Tutorial 5: Advanced Extensions and Best Practices**

* Advanced use cases of extensions
    
* Combining extensions with other Dart features
    
* Best practices and performance considerations
    

  
So Stay tuned and do subscribe to my blog for more updates.
