
Dart Programming Tutorial - Full Course
Learn the Dart programming language in this full tutorial for beginners. Dart is a strictly typed programming language that is used in the Flutter framework to develop cross platform mobile apps. Since Dart supports both AOT (Ahead of time) and JIT (Just In Time) compilation, it delivers extremely fast development cycles and fast execution and startup times. It is a compiled programming language and can also transpile the code into JavaScript. đť Course from Mahmud Ahsan. đ Mahmud's Youtube Channel: https://www.youtube.com/channel/UCtHlgyUw0wLE5Ous9swfFlg đ Mahmud's Github: https://github.com/mahmudahsan/ đ Mahmud's Blog: https://thinkdiff.net/ đ Dart language: https://dart.dev/ đ Flutter Framework: https://flutter.dev/ â¤ď¸ Support for this channel comes from our friends at Scrimba â the coding platform that's reinvented interactive learning: https://scrimba.com/freecodecamp âď¸ Course Contents âď¸ â¨ď¸ (0:00:32) Setup â¨ď¸ (0:03:50) Fundamentals â¨ď¸ (0:11:04) Data Types â¨ď¸ (0:15:44) String, Type Conversion, Constant, null â¨ď¸ (0:23:50) Operators â¨ď¸ (0:39:13) Loop â¨ď¸ (0:48:03) Collections [ List, Set, Map ] â¨ď¸ (1:01:07) Function â¨ď¸ (1:13:49) Class â¨ď¸ (1:37:41) Exception Handling â¨ď¸ (1:41:26) Conclusion -- Learn to code for free and get a developer job: https://www.freecodecamp.org Read hundreds of articles on programming: https://www.freecodecamp.org/news
Dart Programming Tutorial - Full Course
Introduction to Dart Programming Language
Overview of the Tutorial
- Mahmoud Asan introduces the tutorial on Dart, emphasizing its role in developing cross-platform mobile applications using the Flutter framework.
- The tutorial aims to cover fundamental features of Dart, making it accessible for those familiar with other programming languages.
Setting Up Dart SDK
- Instructions are provided for installing the Dart SDK, with options available for Windows, Linux, and Mac users.
- Mahmoud recommends using Visual Studio Code as the preferred editor for writing Dart code.
Using Online Tools and Extensions
Exploring DartPad
- For quick testing without installation, users can utilize DartPad at dartpad.dartlang.org to write and run simple Dart code.
Installing Visual Studio Code Extensions
- To enhance coding experience in Visual Studio Code, a specific Dart extension (version 3.1.0) should be installed for syntax highlighting.
- Users are guided on how to create a new file (
playground.dart
) and access the terminal within Visual Studio Code for running their code.
Understanding Key Features of Dart
Static Typing and Compilation Types
- Dart is described as a statically typed language that also supports dynamic typing through a special type called
dynamic
.
- Two types of compilation are discussed: Ahead-of-Time (AOT) compilation for deployment and Just-In-Time (JIT) compilation during development.
Writing Your First Program
- Every Dart program begins with a
main
function; an example is provided where variables are defined and printed.
Variable Declaration Insights
- The use of
var
allows type inference in variable declaration; if explicitly declared asString
, it cannot hold values of other types like integers.
Error Handling in Type Assignment
- An explanation is given about how assigning incorrect types will result in errors during compilation, reinforcing static typing principles.
Dart Libraries and Core Functionality
Built-in Libraries
Understanding Dart Programming Basics
Importing Core Packages
- In Dart, core packages are automatically imported, so explicit import statements for
dart:core
are generally unnecessary.
- For input/output operations, the
dart:io
library must be imported to facilitate user interaction.
User Input and Output
- The program prompts the user for their name using
stdout.writeLine
, followed by capturing input withstdin.readLineSync
.
- The captured name is printed back to the user using string interpolation (
$name
), demonstrating how variables can be embedded within strings.
Commenting in Dart
- Comments can be added in three ways:
- Inline comments use two forward slashes (
//
).
- Block comments use
/* comment */
.
- Documentation comments start with three forward slashes (
///
) for generating documentation.
Variable Types in Dart
- Dart features two types of programming languages: strongly typed (e.g., C++, Java) where variable types are known at compile time, and dynamically typed (e.g., Python, Ruby) where types are determined at runtime.
- Dart has five basic data types:
int
,double
,String
,bool
, anddynamic
. The latter allows changing value types at runtime.
Defining Variables
- Variables can be defined explicitly with a type or implicitly using the
var
keyword. For example:
- An integer variable can be declared as either
int amount1 = 100;
or simply asvar amount2 = 200;
.
Dynamic Typing in Dart
- A dynamic variable can hold values of any type. For instance, a variable defined as dynamic can first hold an integer and later a string without error.
Object-Oriented Nature of Dart
- Everything in Dart is treated as an object, including primitive data types like integers and booleans. This means even null values are objects.
String Definition in Dart
Understanding String Variables and Type Conversion in Dart
Defining String Variables
- In Dart, string variables can be defined using single quotes or double quotes. For example,
x
is defined with single quotes whilex2
uses double quotes.
- To include an apostrophe within a string defined by single quotes, a backslash (``) is used to escape the apostrophe.
- Raw strings are created by prefixing the string with an 'R', which prevents special characters like newline from being evaluated.
String Interpolation
- Interpolation allows for embedding variable values within strings using the dollar sign (
$
). For instance, ifage
is set to 35, it can be included in a string as "My age is $age".
Multi-line Strings
- Multi-line strings in Dart can be created using three single or three double quotes. This feature allows for easier formatting of longer text blocks.
Type Conversion
Converting Strings to Integers
- The
parse
method of theint
object converts a string representation of a number into an integer. If conversion fails due to invalid characters (e.g., letters), it throws a format exception.
Converting Integers to Strings
- To convert integers or doubles to strings, use the
.toString()
method. This method ensures that numeric values are represented as strings without errors.
Constants and Null Values
Defining Constant Variables
- In Dart, constant variables are declared with the keyword
const
, ensuring their values cannot change at runtime. Examples include defining constants for numbers and booleans.
Handling Null Values
Operators in Dart Programming Language
Basic Arithmetic and Relational Operators
- In Dart, basic arithmetic operations can be performed using standard operators: addition (+), subtraction (-), and modulus (%) for remainder checks.
- Relational operators include equality (==), inequality (!=), greater than (>), less than (<), greater than or equal to (>=), and less than or equal to (<=).
Assignment Operators
- The multiplication assignment operator (*=) allows for shorthand assignments, e.g.,
num *= 2
is equivalent tonum = num * 2
.
- Similar shorthand exists for addition and subtraction, enhancing code efficiency.
Unary Operators
- Dart supports unary operators such as increment (++num or num++) which increase a variable's value by one.
- Logical operators include logical AND (&&) and logical OR (||). Unlike Python, Dart uses symbols instead of keywords for these operations.
Null Safety with the Null-Aware Operator
- The null-aware operator (?) helps prevent errors when accessing properties of potentially null objects. For example,
n?.num
safely accessesnum
ifn
is not null.
- If an object is null, attempting to access its properties without checking will result in a runtime error.
Default Values with Null Coalescing Operator
- The double question mark operator (??) provides a way to assign default values when dealing with null objects. For instance,
number = n?.num ?? 0
assigns zero ifn
is null.
Understanding Nonlinear Operators and Conditional Statements in Dart
Nonlinear Operators
- A nonlinear operator is introduced, demonstrating how to assign a default value using the double question mark (
??
) operator. If a variable is null, it assigns "Hello" as the default.
- The importance of checking for null values is emphasized; failing to do so can lead to program errors. Understanding this operator can prevent issues in programming.
Ternary Operator
- The ternary operator is explained with an example where
x
is checked for evenness by using the remainder operation. Ifx % 2 == 0
, it prints "even"; otherwise, it prints "odd".
- Changing the value of
x
from 100 to 101 illustrates how the ternary operator evaluates conditions dynamically based on variable values.
Type Test Operator
- A type test operator checks if a variable (e.g.,
x
) is of integer type. If true, it prints "integer". This highlights Dart's ability to enforce type safety.
- The discussion transitions into conditional statements using
if
,else if
, andelse
. An example checks divisibility by two or three and provides outputs accordingly.
Conditional Logic with Switch Statement
- The switch statement serves as an alternative to multiple if conditions. It evaluates a variable against several cases and executes corresponding actions.
- An example demonstrates how different cases are handled within a switch statement, including a default case when no other conditions are met.
Looping Constructs in Dart
- Introduction to looping constructs in Dart, specifically the standard for loop. It iterates through numbers from 1 to 10 while explaining initialization, condition checking, and incrementing logic.
Understanding Loops in Dart Programming
Standard For Loop
- The standard for loop iterates through a range of numbers, such as from 1 to 10.
- A variable
number
is defined as an array containing integers (1, 2, 3), and the loop prints each value usingfor var n in numbers
.
- The output confirms that the values are printed sequentially: "123".
For Each Loop
- The for each loop is introduced as a higher-order function that simplifies iteration over arrays.
- An arrow function can be used within the for each loop to access and print values elegantly.
- Alternatively, a traditional function can be defined and passed to the for each method, yielding the same output.
While Loop
- A while loop example is provided where a variable
num
starts at 5 and decrements until it reaches zero.
- The program outputs "54321" when executed correctly after saving changes.
Do While Loop
- A do while loop variation executes its body first before checking the condition; it also produces "54321".
Break Statement
- The break statement allows termination of loops based on conditions; an example shows printing numbers from 0 to 5 before breaking when
i
exceeds five.
Continue Statement
- In a standard for loop designed to print odd numbers, the continue statement skips even numbers by checking if
i % 2 == 0
.
Collections in Dart: List
- Lists in Dart are ordered collections similar to arrays; they can be created using the list class or square brackets.
Understanding Lists and Sets in Dart
Working with Lists
- The speaker discusses how to define a list of object names, demonstrating type inference where the compiler recognizes the list as a string type.
- An example is provided showing that mixed item types can be included in a list, but if a specific type (like string) is desired, it must be explicitly defined.
- Statically typed lists are introduced; attempting to add non-string items results in an error, emphasizing the importance of defining types correctly.
- Mutable lists allow for changing values at specific indices. A demonstration shows replacing an item in the list and its effect on output.
- Copying lists is explained; assigning one list to another does not create a new copy but references the same object. This leads to shared changes between both variables.
Utilizing Spread Operator
- The spread operator (
...
) is introduced as a method for creating distinct copies of lists. This allows for independent manipulation without affecting the original list.
Introduction to Sets
- Sets are described as unordered collections of unique items. The speaker demonstrates defining sets using curly braces and highlights their uniqueness by showing duplicate entries being stored only once.
Defining Empty Sets
- To define an empty set correctly, specifying its type is necessary; otherwise, it defaults to a hashmap. This distinction is crucial for proper data structure usage.
Understanding Maps
How to Create and Use Maps in Dart Programming
Creating Maps with Keys and Values
- In Dart, maps can be created easily using keys to access values. For example, using the key "fifth" retrieves the value "golden rings."
- An empty map can be defined using the
Map
class. You can add key-value pairs by specifying them within square brackets.
- Another method to create a map is by using curly braces, where you define key-value pairs separated by colons.
- Each function in Dart is an object of the class function. The return type of a function can be dynamic or void if it does not return anything.
Defining Functions in Dart
- A function named
square
can take parameters and return their square by multiplying the input number with itself.
- A second function called
showOutput
takes a message as a parameter and prints it to the terminal.
- The
square
function demonstrates dynamic typing, allowing it to return either integers or doubles based on input.
Using Arrow Functions and Anonymous Functions
- Dart allows for concise function definitions through arrow functions (fat arrows), which simplify syntax for single-expression functions.
- Anonymous functions (or lambda expressions in other languages like Python) are also supported, enabling inline definitions without naming them explicitly.
Higher Order Functions and Parameters
- The
forEach
method is an example of a higher-order function that accepts another function as its parameter for iteration over lists.
Understanding Positional and Named Parameters in Dart
Positional Arguments
- The discussion begins with an explanation of positional arguments, using an arrow function that takes two parameters:
num1
andnum2
. The function combines these values and returns the result.
- When calling the function, values are passed directly, which assigns them to
num1
andnum2
based on their positions.
Named Parameters
- Transitioning to named parameters involves using curly braces. This allows for more flexibility when calling functions since you can specify parameter names explicitly.
- An example is provided where
num1
remains a positional parameter whilenum2
is defined as a named parameter. If no value is provided fornum2
, it should default to zero.
Handling Optional Named Parameters
- A conditional operator (
??
) is introduced to handle cases where the optional named parameter might not be provided. This ensures that if no value is given, a default value (zero) will be used instead.
- The use of default values for named parameters simplifies function calls by allowing defaults without additional checks.
Making Positional Parameters Optional
- To make a positional parameter optional, square brackets are added around the parameter definition. This change allows the program to run successfully even if fewer arguments are passed during invocation.
Introduction to Classes in Dart
Defining a Class
- The concept of classes in Dart is introduced as blueprints for creating custom types. A class encapsulates related data (attributes like name and age) and methods (functions associated with the class).
Creating Methods within Classes
- Methods are defined within classes; they perform actions related to the class's attributes. An example method prints out information about a person without taking any parameters.
Understanding Constructors in Dart
Instantiating Objects and Accessing Methods
- The parentheses after the class name instantiate an object, assigning it to a variable (e.g.,
personOne
). To access methods likeshowOutput
, use dot notation (e.g.,personOne.showOutput
).
- To access properties such as
name
andage
, you can use dot notation (e.g.,personOne.name
for "Muhammad" andpersonOne.age
for 35).
Default Constructor in Dart
- A constructor is a method without a return type, automatically called when an object is instantiated. In Dart, the constructor's name matches the class name.
- If no age is provided during instantiation, a default value of 18 is assigned. This can be done using the keyword
this
to refer to instance fields.
Using Shortcuts in Constructors
- When parameters match property names, you can simplify constructors by directly assigning values with
this
. If no additional logic is needed, curly braces can be omitted.
Creating Multiple Instances
- You can create multiple instances of a class (e.g.,
personTwo
) using type inference with the var keyword. Each instance maintains its own state.
Named Constructors
- Besides default constructors, named constructors allow for different initialization patterns. For example, defining a constructor as
Person.guest()
allows creating objects with preset values.
- When calling named constructors without passing values, they will utilize their defined defaults instead of the default constructor.
Immutability with Final Keyword
- To create unchangeable fields within a class after initialization, use the final keyword. This prevents reassignment once set.
- Attempting to change a final variable results in an error detected by IDE extensions; removing final allows reassignment.
Understanding Constants in Dart
Defining Constants with Final and Const Keywords
- The
final
keyword allows you to define properties as constants that can only be assigned once, either through a default constructor or named constructor.
- The
const
keyword creates compile-time constants that cannot change at runtime. In contrast,final
variables can be assigned values at runtime using constructors.
- To access static variables (like those defined with
const
) within a class, use the class name followed by the property name (e.g.,ClassName.propertyName
).
- Instance properties differ for each object, while static properties remain consistent across all instances of a class.
Using Final and Const Outside of Classes
- When defining constants outside of classes, both
final
andconst
behave similarly; they cannot be reassigned after their initial assignment.
- An example shows how to declare final variables like names and ages without needing type annotations due to type inference.
Class Inheritance in Dart
Implementing Class Inheritance
- Use inheritance in Dart with the
extends
keyword to add features to existing classes without affecting all instances.
- A new class (
Car
) inherits from an existing class (Vehicle
). It introduces additional properties while retaining inherited ones.
Constructor Behavior in Inherited Classes
- When creating an instance of a subclass (
Car
), parameters for inherited properties are passed using thesuper
keyword along with a colon operator after the subclass constructor's parentheses.
- The superclass method can be called within the subclass using the syntax:
super.methodName()
, allowing access to inherited functionality.
Example Implementation
- An example demonstrates creating an object of the subclass (
Car
) and passing model, year, and price during instantiation.
Understanding Method Overriding and Getters/Setters in Dart
Method Inheritance and Overriding
- The method
showOutput
is called from a superclass, which prints the model and year of a car. This demonstrates how subclasses can inherit methods from superclasses.
- Method overriding occurs when a subclass redefines a method from its superclass. Using the
@override
annotation helps indicate this to other programmers and provides compiler checks for correctness.
- While not mandatory, using the
@override
keyword is good practice as it prevents silent failures if the superclass method changes or renames members.
Getters and Setters in Dart
- Getters and setters provide controlled access to an object's properties. Each instance variable has implicit getters/setters unless explicitly defined.
- A class named
Rectangle
is defined with properties that can be either integers or doubles, showcasing type inheritance in Dart.
- The getter for 'right' uses an arrow function to return calculated values based on other properties, while setters allow modification of these properties through custom logic.
Practical Example of Getters/Setters
- When accessing getters, parentheses are not required; simply use the dot operator. For setters, assign values directly using an equal sign.
- An example illustrates how setting a value through a setter modifies another property based on calculations involving existing values.
Exception Handling in Dart
- Exception handling allows programs to manage runtime errors gracefully using keywords like
throw
,try
,catch
, andfinally
.
- A function named
mustGreaterThanZero
throws an exception if input is zero or negative. This highlights how exceptions can be raised intentionally within functions.
Catching Exceptions
- If an exception occurs, it must be caught; otherwise, the program will terminate unexpectedly. The example includes defining error handling within a try-catch block.
- The finally block executes regardless of whether an exception occurred, allowing for cleanup actions or final checks after trying to execute code that may fail.
Understanding Exception Handling in Programming
Overview of Exception Handling
- The discussion begins with an explanation of how exceptions are handled in programming, specifically mentioning a scenario where a value must be greater than zero. An exception message is printed when this condition fails.
- The speaker highlights the use of the
catch
block to capture exceptions and notes that messages can also be printed in thefinally
block, indicating that certain actions will occur regardless of whether an exception was thrown.
Catching Specific Exceptions
- It is explained that using the
catch
keyword allows for handling all types of errors, but for specific error types, one can utilize theon
keyword followed by the exception name to target particular exceptions.
- The speaker mentions a pattern involving
on exception catch e
, which provides another way to handle exceptions but expresses a preference for using traditional try-catch blocks unless necessary.
Conclusion and Further Learning
- The tutorial aims to enhance understanding of programming languages and encourages viewers to explore deeper into frameworks like Flutter.