# Dart Programlama Dili

![](/files/-MEOZ7hoXY4VZv2F86a5)

| Platform                                  | Id                                        |
| ----------------------------------------- | ----------------------------------------- |
| ![](/files/-MEOOcvaUFcDgar65VJu) Twitter  | [@ksckaan1](https://twitter.com/ksckaan1) |
| ![](/files/-MEOOhtb0yUpcb3awuCq) Telegram | [@ksckaan1](https://t.me/ksckaan1)        |
| ![](/files/-MEOOjlO4UyzlUf1sQ-1) Github   | [@ksckaan1](https://github.com/ksckaan1)  |


# ÖNEMLİ

{% hint style="warning" %}
Eğer kodları kopyaladığınızda hata ile karşılaşıyorsanız elle yazmayı deneyin.
{% endhint %}

{% hint style="info" %}
Gördüğünüz hataları ve önerilerinizi Twitter [@ksckaan1](http://twitter.com/ksckaan1) üzerinden mesaj yoluyla bildirebilirsiniz yada geri bildirim yapacağınız sayfanın sağ üst köşesinden **Edit on GitHub** linkine girip **Pull Request** yollayabilirsiniz. Böylece hep beraber güvenilir bir kaynak üretmiş oluruz.
{% endhint %}

{% hint style="info" %}
Sizde bu kaynağı paylaşarak kaynağın yayılmasına yardımcı olabilirsiniz.
{% endhint %}


# Dart Hakkında

Dart, **Google** tarafından geliştirilen **ECMA** tarafından standart haline getirilen genel amaçlı bir programlama dilidir.

Dart dili kullanılarak çapraz-platform web, sunucu, masaüstü, CLI, mobil ve IoT uygulamalar gelitirilebilir.

**Lars Bak** ve **Kasper Lund** tarafından **14 Kasım 2013** tarihinde tasarlanmıştır.

|                                                                      |                                                              |
| -------------------------------------------------------------------- | ------------------------------------------------------------ |
| <p></p><p><img src="/files/-MEOLMEnZ3zbWYARP_HW" alt="Lars Bak"></p> | <p></p><p><img src="/files/-MEOMiGkTX5DVMyGLf5l" alt=""></p> |
| Lars Bak                                                             | Kasper Lund                                                  |

Dosya uzantısı `.dart` şeklindedir.

**dart2js** ile JavaScript koduna çevrilebilir ve **dart2native** ile native uygulama olarak derlenebilir.


# Dart SDK Kurulumu

Dart SDK basit birkaç işlem ile işletim sisteminize kurabilirsiniz.

## Windows

Powershell'i Administratör olarak açalım ve aşağıdaki komutu girelim.

```
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
```

Bu komut ile **Chocolately** paket yöneticisini kurmuş olduk. Test etmek için:

```
choco -v
```

yazarak versiyon numarasını görebilirsiniz.\
Daha sonra buradan `dart-sdk` paketini yüklüyoruz.

```
choco install dart-sdk
```

## GNU/Linux

### Debian Based (Ubuntu, Linux Mint, ElementaryOS)

Aşağıdaki komutları terminalde uyguluyoruz.

```
sudo apt-get update
sudo apt-get install apt-transport-https
sudo sh -c 'wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
sudo sh -c 'wget -qO- https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
```

Sonra;

```
sudo apt-get update
sudo apt-get install dart
```

### Arch Linux Based (Manjaro)

```
sudo pacman -S dart
```

## MacOS

```
brew tap dart-lang/dart
brew install dart
```

## Kontrol edelim:

```
dart --version
```


# VSCode Dart Eklentisi Kurulumu

Dart’ı indirdiğimize göre bize Dart kodlarımızı yazacağımız bir Tümleşik Geliştirme Ortamı (IDE) lazım. IDE’ler kodlarımızı yazarken kodların doğruluğunu kontrol eder ve kod yazarken önerilerde bulunur. Bu da kod yazarken işimizi kolaylaştırır.

Benim tavsiyem çoğu kodlama dilini yazarken kullandığım ve Dart yazanların da popüler olarak kullandığı **Visual Studio Code** programı.

Buradan İndirebilirsiniz

<https://code.visualstudio.com/Download>

Linux İS kullananlara yine kullandıkları dağıtımın uygulama deposundan indirmelerini tavsiye ediyorum.

Visual Studio Code’dan ilerki zamanlarda **vscode** olarak bahsedeceğim.

Dart eklentisinin düzgün bir şekilde kurulabilmesi için bilgisayarımızda **git** komut-satırı uygulaması bulunması gerekir. Git’in yüklü olup olmadığını öğrenmek için komut satırına aşağıdakileri yazın:

`git --version`

Eğer versiyon numarasını gördüyseniz yüklü demektir. Eğer yüklü değilse veya git’i güncellemek istiyorsanız ki, mutlaka öneririm, aşağıda nasıl yükleneceğini görebilirsiniz.

Windows MacOS

Windows için: [Buradan İndirebilirsiniz](https://git-scm.com/download/win)

MacOS: [Buradan İndirebilirsiniz.](https://git-scm.com/download/mac)

**GNU/Linux İşletim Sistemleri**

**Debian/Ubuntu**

`sudo apt-get install git`

**Fedora**

`dnf install git`

**Arch Linux**

`sudo pacman -S git`

**Gentoo**

`emerge --ask --verbose dev-vcs/git`

**openSUSE**

`zypper install git`

**Mageia**

`urpmi git`

Git kurulumunu da yaptığımıza göre VSCode için Dart eklentisini kurabiliriz.

![VSCode Dart Eklentisi](/files/-MEOUasL4YfsUaQWb4z8)

Artık VSCode üzerinden Dart uygulaması geliştirebiliriz.


# Merhaba Dünya

Programlama dünyasında gelenektir, bir programlama dili öğrenilirken ilk önce ekrana **“Merhaba Dünya”** çıktısı veren bir program yazılır. Biz de geleneği bozmadan Dart üzerinde Merhaba Dünya uygulaması yazalım. İlk önce kodları görelim. Daha sonra açıklamasını görelim.

```dart
void main() {
  print("Merhaba Dünya");
}
```

Diğer birçok programlama dili gibi Dart'da **main** fonksiyonuna sahip. Bu fonksiyon içerisinde yazdığımız kodlar program tarafından otomatik yürütülecektir.&#x20;

**main** fonksiyonunun dönüş tipi **void**'tir. Yani bir değer döndürmez.

**print** fonksiyonu ile `"Merhaba Dünya"` yazısını bastırdık.

Kodlarımızı test etmek için VSCode içerisinde `F5` tuşuna basıyoruz.

![Hata Ayıkla Konsolu](/files/-MEOWzZlpgRYI5vHMRmg)

Hata ayıklama konsolu sekmesinden yorumlanan kodumuzun sonucuna ulaşabiliriz.

## Komut Satırı

Kodlarımızı komut satırında test etmek istiyorsak;

```dart
dart run main.dart
```


# Yorum Satırı

Diğer dillerde de olduğu gibi Dart’ta yorum satırı özelliği mevcuttur. Yorum satırı derleyici tarafından işlenmez. Yani görmezden gelinir. Bu bölüme kendiniz için açıklama vs. bilgiler yazabilirsiniz. Dart’ta yorum satırı oluşturmak için 2 yöntem mevcuttur.

**// Çift Taksim Yöntemi**

Bu yöntem ile derlenmesini istemediğimiz yazının başına çift taksim ekleyerek görmezden gelinmesini sağlıyoruz.

```go
//Buraya herhangi birşey yazabilirsiniz
```

**/\* \*/ Taksim-Yıldız Yöntemi**

Bu yöntem ile birden fazla satırın derlemede görmezden gelinmesini sağlayabiliriz.

```go
/* Buraya
herhangi
birşey
yazabilirsiniz */
```


# Veri Tipleri

Dart programlama dilinden 5 ana veri tipi vardır.

1. Number
2. String
3. Boolean
4. List
5. Map

## 1. Number

**Number** ana tipi **numerik** değişkenleri hafızada tutmak içindir. İkiye ayrılır:

### 1.1 Integer

Tam sayılar için kullanılan tiptir. `int` terimi ile kullanılır.

```dart
int sayi = 10;
```

### 1.2 Double

Küsuratlı sayılar için kullanılan tiptir. `double` terimi ile kullanılır.

```dart
double sayi = 5.21;
```

## 2. String

String tipi metinsel ifadeleri hafızada tutmak için kullanılır. `String` terimi ile kullanılır.

```dart
String metin = "Merhaba";
```

## 3. Boolean

**Boolean** veri tipi mantıksal ifadeyi hafızada tutmak için kullanılır. `bool` terimi ile kullanılır.

```dart
bool online = true;
```

## 4. List

**List** veri tipi liste oluşturmamızı sağlar. `List` terimi ile kullanılır.

```dart
List isimler = ["kaan", "erkay", "altan"];
```

## 5. Map

**Map** veri tipi anahtarlı listeler oluşturmamızı sağlar. `Map` terimi ile kullanılır.

```dart
Map kisi = {"isim": "Kaan", "soyisim": "Kuşcu"};
```

## Dynamic ve Var ile Değişken Tanımlama

### 1. Var

**Var** ile atama yaparsak değişkenin tipini belirmemiz gerekmez. Yorumlayıcı yorumlama esnasında verilen değere göre değişkenin tipini belirler. `var` terimi ile kullanılır.

```dart
var degisken1 = "metin";
var degisken2 = 156;
var degisken3 = false;
```

### 2. Dynamic

**Dynamic** veri tipi değerin tipinin yorumlayıcı tarafından algılanmasını sağlar. Var'dan farkı içerisine başka türde değer atandığında değişken yeni atanan değerin tipine dönüşür. `dynamic` terimi ile kullanılır.

```dart
 dynamic degisken = "metin";
 dynamic degisken = 156;
 dynamic degisken = false;
```


# Aritmetik Operatörler

Aritmetik operatörler programlamada matematiksel işlemler yapabilmemize olanak sağlar.

| Operatör | Açıklama                    | Örnek |
| -------- | --------------------------- | ----- |
| +        | Toplar                      | 2+5   |
| -        | Çıkarır                     | 10-3  |
| \*       | Çarpar                      | 3\*4  |
| /        | Böler                       | 10/2  |
| %        | Bölümden kalanı verir (Mod) | 10%3  |
| ++       | 1 arttırır                  | 1++   |
| --       | 1 eksiltir                  | 1--   |


# İlişkisel Operatörler

İlişkisel operatörler programlamada iki veriyi birbiriyle karşılaştırabilmemize olanak sağlar. Karşılaştırma doğrulanıyorsa **true** değer, doğrulanmıyorsa **false** değer alır.

| Operatör | Açıklama                                                 | Örnek |
| -------- | -------------------------------------------------------- | ----- |
| ==       | İki verinin eşitliği                                     | 2==2  |
| !=       | İki verinin eşitsizliği                                  | 2!=3  |
| >        | <ol><li>verinin 2. veriden büyüklüğü</li></ol>           | 5>3   |
| <        | <ol><li>verinin 2. veriden küçüklüğü</li></ol>           | 4<6   |
| >=       | <ol><li>verinin 2. veriden büyük veya eşitliği</li></ol> | 4>=6  |
| <=       | <ol><li>verinin 2. veriden küçük veya eşitliği</li></ol> | 3<=8  |


# Mantıksal Operatörler

Mantıksal operatörler birden fazla mantıksal veriyi kontrol eder ve kullandığımız operatöre göre mantıksal değer döndürür.

| Operatör | Açıklama                                                                 | Örnek                 |
| -------- | ------------------------------------------------------------------------ | --------------------- |
| &&       | VE operatörüdür. 2 koşulda doğruysa true değer verir                     | 2==2 && 2==3 (false)  |
| \|\|     | VEYA operatörüdür. 2 koşuldan ikisi veya biri doğru ise true değer verir | 2==2 \|\| 2==3 (true) |
| !        | DEĞİL operatörüdür. Koşul sonucunun tersini verir                        | !(2==2) (false)       |


# Atama Operatörleri

Atama operatörleri değişkenlere ve sabitlere değer atamak için kullanılır. Aşağıdaki tabloda c’nin değeri 10’dur. (c=10)

| Operatör | Açıklama                       | Örnek |
| -------- | ------------------------------ | ----- |
| =        | Atama Operatörüdür             | c=2   |
| +=       | Kendiyle toplar                | c+=2  |
| -=       | Kendinden çıkarır              | c-=2  |
| \*=      | Kendiyle çarpar                | c\*=2 |
| /=       | Kendine böler                  | c/=2  |
| %=       | Kendine bölümünden kalanı atar | c%=3  |


# Sabitler

Sabitler bir kere tanımlandıktan sonra değiştirilemeyen verilerdir. `const` terimi ile kullanılırlar.

İki adet tanımlama yöntemi vardır.

## 1. Sadece const ile

```dart
const piSayisi = 3.14;
```

`piSayisi`'nın tipini belirtmedik sadece `const` terimini kullandık.

## 2. Const ve Tip ile

```dart
const int sayi = 156;
```

`sayi`'nin `integer` tipinde bir sabit olduğunu belirttik.


# Tür Dönüşümü

Dart üzerinde veri tiplerini birbirine dönüştürebiliriz.

### Örnek:

```dart
int sayi = 15;
String yazi = sayi.toString();
double sayi1 = 15.23;
int sayi2 = sayi1.toInt();
```

{% hint style="info" %}
`toString()` : String'e dönüştürme\
`toInt()` : Integer'a dönüştürme\
`toDouble()` : Double'a dönüştürme
{% endhint %}

Bir değişkenin veya sabitin veri tipini öğrenmek için `runtimeType` fonksiyonunu kullanabiliriz.

```dart
main() {
  int i = 5;

  print(i.runtimeType); //int
}
```


# List

Bu bölümde **List** veri tipini detaylıca inceleyeceğiz.

**List**, liste oluşturmamızı sağlayan bir veri tipidir. `List` terimi ile kullanılır.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
```

## Index Nedir?

`Index`, **List** içindeki elemanların sıra numarasıdır. **Index** sırası 0'dan başlar. Yukarıdaki örneğe göre:

```dart
print(isimler[1]); //Erkay
```

## List Uzunluğu

`List` uzunluğunu `length` fonksiyonu (getter) iliştirilerek öğrenilebilir.

```dart
print(isimler.lenght); //4
```

## List Ters Çevirme

```dart
print(isimler.reversed); //(Emir, Altan, Erkay, Kaan)
```

## First ve Last

```dart
print(isimler.firt); //ilk indexi verir.
print(isimler.last); //son indexi verir.
```

## isEmpty ve isNotEmpty

`isEmpty` boşsa `true`, `isNotEmpty` boş değilse `true` döndürür.

```dart
print(isimler.isEmpty); //false
print(isimler.isNotEmpty); //true
```

## runtimeType

`List`'in veri tipini verir. Veri tipi belirlenmemişse `dynamic`'tir.

```dart
print(isimler.runtimeType); //List<dynamic>
```

## add

`List`'e eleman ekler.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
isimler.add("Ahmet");
print(isimler); //[Kaan, Erkay, Altan, Emir, Ahmet]
```

## addAll

Başka bir `List`'teki elemanları ekler.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
List yeniIsimler = ["Ahmet", "Mehmet", "Ali"];
isimler.addAll(yeniIsimler);
print(isimler);
//[Kaan, Erkay, Altan, Emir, Ahmet, Mehmet, Ali]
```

## asMap

`Map`'e dönüştürür.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
print(isimler.asMap());
//{0: Kaan, 1: Erkay, 2: Altan, 3: Emir}
```

## clear

`List` içeriğini temizler.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
isimler.clear();
print(isimler); // []
```

## fillRange

Belirlediğimiz index aralığını `null` ile doldurur. **Null** belirlenmemiş veri tipidir. Yani boştur.

```dart
 List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
 isimler.fillRange(1, 3);
 print(isimler); //[Kaan, null, null, Emir]
```

## getRange

Belirlediğimiz aralığı verir.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
print(isimler.getRange(1, 3)); // (Erkay, Altan)
```

## indexOf

Yazılan nesnenin indexini verir.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
print(isimler.indexOf("Altan")); // 2
```

## insert

Belirlenen indexe eleman ekleme.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
print(isimler); // [Kaan, Erkay, Altan, Emir]
isimler.insert(2, "Ali");
print(isimler); // [Kaan, Erkay, Ali, Altan, Emir]
```

## insertAll

Belirlenen indexe `List` ekleme.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
List isimlerYeni = ["Ali", "Mehmet", "Ahmet"];
print(isimler); // [Kaan, Erkay, Altan, Emir]
isimler.insertAll(2, isimlerYeni);
print(isimler);
// [Kaan, Erkay, Ali, Mehmet, Ahmet, Altan, Emir]
```

## lastIndexOf

Aramaya sondan başlayarak yazılan elemanın indexini verir.

```dart
List isimler = ["Kaan", "Erkay", "Kaan", "Emir"];
print(isimler.lastIndexOf("Kaan")); // 2
```

## remove

Yazılan elemanı kaldırır.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
  isimler.remove("Altan");
  print(isimler); // [Kaan, Erkay, Emir]
```

## removeAt

Belirtilen indexteki elemanı kaldırır.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
isimler.removeAt(1);
print(isimler); // [Kaan, Altan, Emir]
```

## removeLast

`List`'in son elemanını kaldırır.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
isimler.removeLast();
print(isimler); // [Kaan, Erkay, Altan]
```

## removeRange

Belirlenen aralığı kaldırır.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
isimler.removeRange(1, 3);
print(isimler); // [Kaan, Emir]
```

## replaceRange

Belirtilen aralığı değiştirir.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
isimler.replaceRange(1, 3, ["Ahmet", "Merhmet"]);
print(isimler); // [Kaan, Ahmet, Merhmet, Emir]
```

## setAll

Belirtilen indexten itibaren belirtilen `List` elemanlarının atanması.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
List isimlerYeni = ["İsmail", "Ahmet", "Ali", "Gökhan"];
isimler.setAll(0, isimlerYeni);
print(isimler); // [İsmail, Ahmet, Ali, Gökhan]
```

## setRange

Belirtilen aralığa atama.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
isimler.setRange(1, 3, ["İsmail", "Ali"]);
print(isimler); // [Kaan, İsmail, Ali, Emir]
```

## shuffle

`List`'i rastgele olarak karıştırır.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
isimler.shuffle();
print(isimler); // [Emir, Erkay, Altan, Kaan]
```

## sort

List'i veri tipine göre sıralar.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
isimler.sort();
print(isimler); // [Altan, Emir, Erkay, Kaan]
```

## sublist

`List`'i verilen indexten başlatır.

```dart
List isimler = ["Kaan", "Erkay", "Altan", "Emir"];
print(isimler.sublist(2)); // [Altan, Emir]
```


# Map

**Map**, birden fazla boyutu olan **List**'tir. Örnek:

```dart
Map isimler = {1: "Kaan", 2: "Erkay", 3: "Altan", 4: "Emir"};
```

Yukarıda 2 boyutlu `map` örneği verilmiştir. Çok boyutlu bir örnek verecek olursak:

```dart
Map isimler = {
 1: {"isim": "Kaan", "soyIsim": "Kuşcu", "yas": 23},
 2: {"isim": "Emir Alper", "soyIsim": "Babur", "yas": 27},
 3: {"isim": "Altan", "soyIsim": "Aydemir", "yas": 22}
};
```

`Map` üzerinde istenilen bölgeyi göstermek için:

```dart
print(isimler[1]); // {isim: Kaan, soyIsim: Kuşcu, yas: 23}
print(isimler[1]["isim"]); // Kaan
```

## Map Fonksiyonları

### isEmpty

Map boş ise **true** verir.

```dart
print(isimler.isEmpty); // false
```

### isNotEmpty

Map boş değilse **true** verir.

```dart
print(isimler.isNotEmpty); // true
```

### keys

Anahtarları listeler.

```dart
print(isimler.keys); // (1, 2, 3)
```

### lenght

Map'in uzunluğunu verir.

```dart
print(isimler.length); // 3
```

### values

keys'in tersi olarak değerleri listeler.

```dart
print(isimler.values); // ({isim: Kaan, soyIsim: Kuşcu, yas: 23}, {isim: Emir Alper, soyIsim: Babur, yas: 27}, {isim: Altan, soyIsim: Aydemir, yas: 22})
```

### addAll

Başka bir Map'i ekler. Aynı değerler var ise üzerine yazar.

```dart
main() {
  Map isimler = {
    1: {"isim": "Kaan", "soyIsim": "Kuşcu", "yas": 23},
    2: {"isim": "Emir Alper", "soyIsim": "Babur", "yas": 27},
    3: {"isim": "Altan", "soyIsim": "Aydemir", "yas": 22}
  };
  Map yeniIsimler = {
    4: {"isim": "Gökhan", "soyIsim": "Bingül", "yas": 26},
    5: {"isim": "İsmail", "soyIsim": "Tunç", "yas": 22},
    6: {"isim": "Emre", "soyIsim": "Gülşen", "yas": 23}
  };
  isimler.addAll(yeniIsimler);
  print(isimler);
}
```

> {1: {isim: Kaan, soyIsim: Kuşcu, yas: 23}, 2: {isim: Emir Alper, soyIsim: Babur, yas: 27}, 3: {isim: Altan, soyIsim: Aydemir, yas: 22}, 4: {isim: Gökhan, soyIsim: Bingül, yas: 26}, 5: {isim: İsmail, soyIsim: Tunç, yas: 22}, 6: {isim: Emre, soyIsim: Gülşen, yas: 23}}

### clear

Map'in içini boşaltır.

```dart
print(isimler); // {}
```

### containsKey

Anahtarı içerip içermediğini kontrol eder.

```dart
print(isimler[1].containsKey("isim")); // true
```

### containsValue

Değeri içerip içermediğini kontrol eder.

```dart
print(isimler[1].containsValue("Kaan")); // true
```

### forEach

Map'in eleman sayısına göre döndü işlemi yapar. forEach fonksiyonu 2 parametre alır. 1. anahtar parametresi, 2. değer parametresidir.

```dart
isimler.forEach((anahtar, deger) {
    print(anahtar.toString() + ". anahtarda : " + deger.toString());
});
```

> 1. anahtarda : {isim: Kaan, soyIsim: Kuşcu, yas: 23}
> 2. anahtarda : {isim: Emir Alper, soyIsim: Babur, yas: 27}
> 3. anahtarda : {isim: Altan, soyIsim: Aydemir, yas: 22}

### remove

Belirtilen anahtardaki değeri kaldırır.

```dart
isimler.remove(2);
print(isimler);
```

> {1: {isim: Kaan, soyIsim: Kuşcu, yas: 23}, 3: {isim: Altan, soyIsim: Aydemir, yas: 22}}

### update

Belirtilen anahtardaki değeri günceller.

```dart
isimler.update(
      2, (value) => {"isim": "Cüneyt", "soyIsim": "Ayder", "yas": 28});
print(isimler);
```

> {1: {isim: Kaan, soyIsim: Kuşcu, yas: 23}, 2: {isim: Cüneyt, soyIsim: Ayder, yas: 28}, 3: {isim: Altan, soyIsim: Aydemir, yas: 22}}

### Diğerleri

**updateAll** = Tüm değerleri günceller.

**runtimeType** = Çalışma zamanındaki veri tipini gösterir.


# Fonksiyonlar

Fonksiyonlar, okunabilir, düzenlenebilir ve yeniden kullanılabilir kod blokları oluşturmamızı sağlar. Bu kod bloklarının içerisinde işlemler yapabiliriz.

Fonksiyonlar tanımlandıktan sonra başka bir yerden çağrılabilir. Bu özelliği kod bloğunu yeniden kullanılabilir yapar. Ayrıca kodun okunabilirliğini arttırır.

## Adımlar&#x20;

1. Fonksiyonun Tanımlanması
2. Fonksiyonun Çağrılması
3. Fonksiyonun Değer Döndürmesi
4. Fonksiyonun Parametresi

### 1. Fonksiyonun Tanımlanması

Fonksiyonun tanımlanması aşağıdaki gibi yapılır.

```dart
void merhaba() {
  print("merhaba");
}
```

Yukarıda ekrana `"merhaba"` yazan bir fonksiyon oluşturduk. Bu fonksiyonumuzu **merhaba** olarak adlandırdık.

### 2. Fonksiyonumuzun Çağrılması

Yukarıdaki merhaba fonksiyonunu kullanmak istersek aşağıdaki gibi yaparız.

```dart
void merhaba() {
  print("merhaba");
}

void main() {
  merhaba();
}
```

Yukarıda gördüğünüz gibi **main** fonksiyonu içerisinde **merhaba** fonksiyonunu kullandık.

### 3. Fonksiyonun Değer Döndürmesi

Fonksiyonlar bir eylem gerçekleştirmek yerine bize bir değer de döndürebilir. Bu işlemi `return` terimi ile yaparız.

```dart
int sayi() {
  return 10;
}

void main() {
  print(sayi());
}
```

Yukarıdaki kodları incelediğimizde, ilk gördüğümüz farklılık, bu sefer `void` terimi ile değil de `int` terimi ile fonksiyon oluşturduk. Bunun sebebi `sayi()` fonksiyonunda `return` ettiğimiz değer **integer** tipinde olmasıdır. Fonksiyon oluştururken, eğer bir değer döndürecekse fonksiyon isminden önce **return** tipini belirtmemiz gerekir.

#### Peki void nedir?

`void` terimini ise fonksiyonumuz bir değer döndürmüyorsa kullanırız. Dart'ta bir fonksiyonda `return` yoksa `return tipi` kullanmamızda zorunlu değildir.

```dart
merhaba() {
  print("merhaba");
}

main() {
  merhaba;
}
```

Yukarıda gördüğünüz gibi, aslında `void` yazmamıza gerek yok.

Özet olarak, eğer fonksiyon bir değer döndürüyorsa dönecek değerin tipi belirtiriz. Değer döndürmüyorsa `void` yazarız veya hiçbir şey yazmayız.

### 4. Fonksiyon Parametresi

Parametreler değerleri işlemlere iletmek için kullanılır. Yani bir fonksiyona işlemlerinde kullanması için parametreler yollayabiliriz.

```dart
int topla(int a, int b) {
  return a + b;
}

main() {
  print(topla(5, 10));
}
```

Kodlarımıza bakalım;

`topla` adında bir fonksiyon oluşturduk. bu fonksiyonun başta `int` tipinde bir değer döndüreceğini belirttik. Parantez içine baktığımızda `int a` ve `int b` terimlerini görüyoruz. Bunlar bizim parametrelerimiz. Bu parametreleri fonksiyonumuzun içerisinde topladık ve `return` ettik.

`main` fonksiyonu içerisinde de `topla` fonksiyonumuza iki değer girerek çağırıp ekrana bastırdık.

#### Fonksiyon Parametreleri Hakkında Tüyo

Parametreleri tanımlarken aşağıdaki gibi de tanımlayabiliriz.

```dart
int topla(int a, b) {
  return a + b;
}
```

`b`'nin tipini yazmadık, çünkü tipini bir önceki parametrenin tipi olarak belirlendi.

## Varsayılan Fonksiyon Parametreleri

Fonksiyondaki parametrelere girilmemesi dahilinde otomatik değer atanabilir. Örneğimiz;

```dart
int carp(int a, [int b = 2]) {
  return a * b;
}

main() {
  print(carp(5)); //10
  print(carp(5, 3)); //15
}
```

`carp` fonksiyonunu incelediğimizde, `a` adında `interger` tipinde bir parametre oluşturduk. Köşeli parantez içerisine `b` değişkeni tanımladık ve `2` değerini verdik. Yani `b` parametresinin girilmemesi durumunda `b` parametremizin değeri `2` olacaktır.

## Belirli Parametreyi Girme

```dart
int carp({int a, b}) {
  return a * b;
}

main() {
  print(carp(a: 5, b: 4));
}
```

`carp` fonksiyonunun parametrelerini tanımlıyorken, parantez içerisine ayrıca süslü parantez koyduğumuza dikkat çekmek isterim. Böyle fonksiyon başka bir yerden çağrılırken, tıpkı `map` kullanımındaki gibi değer yollayacağımız parametreyi de belirtiriz.&#x20;


# Arrow Fonksiyonlar

**Arrow** (ok) fonksiyonlar ile tek satırlık fonksiyonlar oluşturabiliriz. Bu şekilde daha kısa fonksiyonlar yazabiliriz.

```dart
int topla(int a, b) => a + b;

main() {
  print(topla(5, 10));
}
```

`topla` fonksiyonunun parametrelerine kadar normal fonksiyonlarla aynıdır. Daha sonrasında `=>` kullanarak tek satırlık işlem yapabiliriz. Dikkat ettiyseniz `topla` fonksiyonu `int` tipinde `return` ediyor. Fakat fonksiyonun hiçbir yerinde `return` terimi bulunmuyor. Çünkü gerek yok


# String İçinde Değişken ve Fonksiyon Kullanma

Bu işlemi `${}` ile yapabiliriz. İşte örneğimiz;

```dart
int carp(int a, b) {
  return a * b;
}

main() {
  print("3 X 5 = ${carp(3, 5)}");
}
```

Yukarıda gördüğümüz gibi `print` fonksiyonu içerisine **`${`**`carp(3, 5)`**`}`** ekleyerek `carp` fonksiyonundan dönen sonucu `string`'e eklemesini sağladık.

Bunu aynı şekilde değişkenler için de kullanabiliriz.

```dart
main() {
  String isim = "Kaan";
  print("Merhaba ${isim}!");
}
```


# Döngüler

Bazen, belirli kodların tekrarlanması gerekir. Bu işlemi döngüler ile gerçekleştirebiliriz.&#x20;

![Döngü Çeşitleri Şeması](/files/-MEU3ChjyrKFL3shjNu1)

## 1. For Döngüsü

```dart
main() {
  for (var i = 0; i < 10; i++) {
    print(i);
  }
}
```

`for` terimi ile döngümüzü tanımlıyoruz. `i` isminde değişken oluşturup değerine `0` veriyoruz. `for` döngümüzün `i`'nin değeri `10`'dan küçük olduğu takdirde çalışmasını belirtiyoruz. Her döngü gerçekleştiğinde `i++` ile **i**'nin değerini **1** arttırıyoruz. Döngü içerisinde de `i`'nin değerini ekrana bastırdık.

### 1.1 For in Döngüsü

`For in` döngüsü ile bir listenin içeriği ile ilgili işlemler yapabiliriz.

```dart
main() {
  List isimler = ["kaan", "erkay", "altan"];

  for (var isim in isimler) {
    print(isim);
  }
}
```

`For in`'in `For`'dan farkı belirlediğimiz listenin uzunluğunda işlem yapmasıdır. `isimler` isminde bir liste oluşturduk ve içerisinde birkaç isim girdik.

Daha sonra aşağısında `for` döngüsü oluşturduk ve parantezler içine `var isim` diyerek `isim` değişkeni oluşturduk. `in isimler` diyerek de `isim` değişkeninin her bir `isimler` indeksini kullanmasını sağladık. En sonda `isim` değişkenini ekrana bastırdık.

### 1.2 ForEach Döngüsü Fonksiyonu

Bu döngü diğerlerine göre biraz farklı çalışıyor. Bu döngü bir liste değişkenine bağlanıyor. Örneğimizi görelim;

```dart
main() {
  List isimler = ["kaan", "erkay", "altan"];

  isimler.forEach((isim) {
    print(isim);
  });
}
```

`isimler` adında bir liste oluşturup, içerisine birkaç isim yazdık.

Daha sonra `isimler` değişkenine `forEach()` fonksiyonu iliştirdik. Bu fonksiyonun parametresinde listenin indeksleri için hangi terimi hangi değişkeni oluşturacağımızı yazdık. Son olarak da ekrana `isim` değişkenini bastırdık.

## 2. While Döngüsü

```dart
main() {
  int i = 10;

  while (i != 0) {
    print(i);
    i--;
  }
}
```

`while` döngüsü ilk olarak döngünün gerçekleşmesi için gerekli olan şartı sorgular. Yukarıdaki kodumuzda şart `i`'nin `0`'a eşit olmadığı sürece döngünün çalışmasıdır. Döngü her tekrarlandığında `i`'nin değeri ekrana bastırılır ve `i`'nin değeri `1` eksiltilir. Daha sonra `i`'nin değeri `0`'a kadar düşünce döngü sonlanır.

## 3. Do While Döngüsü

```dart
main() {
  int i = 10;

  do {
    print(i);
    i--;
  } while (i != 0);
}
```

`do while` döngüsü ilk önce döngü işlemlerini gerçekleştirir. Daha sonra koşulu kontrol eder. Bu da `while`'ın ters mantığı oluyor.


# If - Else

If ve Else kelimelerinin Türkçe karşılığına bakacak olursak;

**If :** Eğer, **Else :** Yoksa anlamına gelir. **If-Else** akışı koşullandırmalar için kullanılır. Diğer dillerin aksine koşul parametresi parantezler içine yazılmaz. Teorik kısmı bırakıp uygulama kısmına geçelim ki daha anlaşılır olsun.

```dart
if (koşul){
  //koşul sağlandığında yapılacak işlemler
}else{
  //koşul sağlanmadığında yapılacak işlemler
}
```

Yukarıdaki kod tanımına göre örnek bir program yazalım;

```dart
main() {
  int i = 5;
  if (i == 5) {
    print("i'nin değeri 5'tir.");
  } else {
    print("i'nin değeri 5 değildir.");
  }
}
```

Yukarıdaki kodları inceleyelim. `i`’nin değerini `5` verdik. `if` teriminin sağında `i`’nin `5` 'e eşitliği koşulunu sorguladık. Eşitse ekrana `i’nin değeri 5’tir.` yazısını bastıracak. Değilse `i’nin değeri 5 değildir.` yazısı bastıracak. `i`’nin değeri `5` olduğu için ekrana `i’nin değeri 5’tir.` yazısını bastırdı. If-Else akışında else kullanmamamız else’nin kod bloğunu boş bırakmamız ile aynı anlama gelir.

```dart
main() {
  int i = 5;
  if (i == 5) {
    print("i'nin değeri 5'tir.");
  }
}
```

Yukarıda sadece **if** deyimini girdik. **Else**’yi girmedik. Burada sonuçlanan olay, **i**’nin değeri **5**'e eşitse `i'nin değeri 5'tir.` yazısını ekrana bastırır. **Else** deyimini girmediğimiz için şartın sağlanmaması durumunda hiçbir işlem gerçekleşmez. Çıktımız **i**’nin değeri **5**'e eşit olduğu için `i’nin değeri 5'tir.` çıkar.

**ELSE-IF KULLANIMI**

**If-Else** akışında birden fazla koşul kontrolü ekleyebiliriz. Bunu **else if** deyimi ile yapabiliriz. Kısaca bakacak olursak;

```dart
main() {
  int i = 3;
  if (i == 5) {
    print("i'nin değeri 5'tir.");
  } else if (i == 3) {
    print("i'nin değeri 3'tür.");
  } else {
    print("i'nin değeri bilinmiyor");
  }
}
```

`else if` deyiminin yazılışını da gördük. Açıklamaya gelirsek, `else if` deyimi kendinden önceki deyimin koşulunun sağlanmaması halinde bir sonraki koşulu kontrol ettirir. **If-Else** akışında istenildiği kadar `else if` deyimi eklenebilir.

\
**Koşullar İçerisinde Operatör Kullanımı**\
Koşullar içerisinden mantıksal ve ilişkisel operatörler kullanılabilir. Operatörleri görmüştük. Operatör kullanarak örnekler yapalım.

```dart
main() {
  int a = 1, b = 3, c = 5;

  if (a != b) {
    print("a eşit değildir b");
  }
  if (a < c) {
    print("a küçüktür c");
  }
  if (a < b && b < c) {
    print("a küçüktür b ve b küçüktür c");
  }
}
```

Çıktımız aşağıdaki gibi olacaktır:

> a eşit değildir b\
> a küçüktür c\
> a küçüktür b ve b küçüktür c


# Switch - Case

**Switch**, bir değişkeni anahtar olarak belirler. **Case** ise bu değişkenin durumunu kontrol eder. Mantık olarak **if-else**'e benzer. Farkı ise bunu sadece bir değişken üzerinde uygulamasıdır. Örneğimiz:

```dart
main() {
  int i = 5;
  switch (i) {
    case 0:
      print("i'nin değeri 0'dır.");
      break;
    case 5:
      print("i'nin değeri 5'tir.");
      break;
    case 10:
      print("i'nin değeri 10'dur.");
      break;
    default:
      print("i'nin değeri bilinmiyor.");
  }
}
```

`switch(i)` yazarak i değişkenini anahtar olarak belirledik. Aşağısındaki `case 0` ile **i**'nin değerinin **0** olup olmadığını sorguluyoruz. **0** ise **print** ile `"i'nin değeri 0'dır."` yazdırdık. **break**'in anlamı ise **case** doğru olduğunda diğer **case**'leri kontol etmemesi içindir. **default** ise **else** ile aynı mantıktadır.

```dart
main() {
  int i = 0;
  switch (i) {
    case 0:
      print("mesajım 1");
      continue durumum;
    case 5:
      print("mesajım 2");
      break;
    durumum:
    case 0:
      print("mesajım 3");
      break;

    default:
      print("mesajım 4");
  }
}
```

Yukarıda `continue`'nun kullanımına bir örnek vardık. İnceleyecek olursak;

`i` adlı integer tipinde `0` değeri olan bir değişken tanımladık. Bu değişkeni `switch`'e anahtar değişken olarak yazdık. Değişkenin değerinin `0` olması durumunda ekrana `"mesajım 1"` yazdırmasını istedik ve `continue durumum` yazarak durumum etiketinden devam etmesini istedik. Böylede `case 5`'i atlayarak `durumum:` etiketinden devam etti.


# Sınıflar

## Sınıf Oluşturma

Sınıflar diğer birçok dildeki gibi `class` terimi ile oluşturulur.

```dart
class insan {
  String isim;
  int yas;
  double kilo;
}

main() {
  insan kisi1 = new insan();
}
```

Yukarıda bir `insan` sınıfı oluşturduk. Bu sınıf **isim**, **yas** ve **kilo** gibi özellikleri vardır. Tıpkı bir insanda bulunan özellikler gibi.

Hemen aşağısında, **kisi1** adından **insan** sınıfında bir nesne ürettik. Artık **kisi1** nesnesi bir insan oldu 😉

Peki `kisi1`'in böyle özellikleri var ama bu özelliklerin değerleri yok mu? Tabi ki olacak.

```dart
class insan {
  String isim = "Kaan";
  int yas = 23;
  double kilo = 78.2;
}

main() {
  insan kisi1 = new insan();
}
```

Artık `kisi1` tamamen insan oldu diyebiliriz. `print(kisi1.isim);` yazarak `kisi1`'in isim değişkenini yazdırabiliriz. Ama olaya biraz dikkat ettiğimizde değerlerin `kisi1`'e ait değil de insan sınıfında ait olduğunu görebiliriz. Yani `insan` sınıfı için oluşturulmuş nesnelerin varsayılan değerini girmiş olduk. Çözümümüz Constructors (Yapıcılar);

## Constructors (Yapıcılar)

Yapıcılar bir sınıf nesnesi üretirken değerlerin tanımlanmasında kullanılır. Örneğimiz:

```dart
class insan {
  String isim;
  int yas;
  double kilo;

  insan(String isimGiris, int yasGiris, double kiloGiris) {
    isim = isimGiris;
    yas = yasGiris;
    kilo = kiloGiris;
  }
}

main() {
  insan kisi1 = new insan("Kaan", 23, 78.2);
  print(kisi1.isim);
}
```

Yapıcılar sınıfların içerisine fonksiyon olarak tanımlanır. Bir fonksiyonun yapıcı fonksiyon olması için sınıf ile aynı isme sahip olması gerekir. Yani `insan` sınıfının yapıcısı `insan()` fonksiyonu olmalıdır. Yapıcı fonksiyonlardaki mantık, dışarıdan alınan değerleri sınıf içerisindeki değişkenlere yerleştirmektir. Yapıcı fonksiyondaki parametrelerin isimleri ile sınıf değişkenlerinin isimlerinin aynı olmadığına dikkat çekmek isterim. Bu işlemi `this` işaretçisi ile de yapabiliriz.&#x20;

## This işaretçisi nedir?

**This** işaretçisi, sınıfa özel tanımlı değişkenleri kullanabilmeyi sağlayan işaretçidir. Yapıcımızı bir de `this` ile oluşturalım.

```dart
insan(String isim, int yas, double kilo) {
  this.isim = isim;
  this.yas = yas;
  this.kilo = kilo;
}
```

Yukarıdaki `this` şu işlemi yapıyor. **this = bu**. `isim` parametresinden gelen değer, `this.isim` ile bu sınıfın `isim` değişkenine atansın.

## This ile Yapıcı oluştururken Kolay Yöntem

```dart
insan(this.isim, this.yas, this.kilo) {}
```

Yukarıdaki yapıcıyı oluştururken parametreleri `this` işaretçisi ile yazdık. Böylece atama işlemine gerek kalmadan parametreler üzerinden atanmasını sağladık.

## Sınıf Nesnesi Oluştururken Belirli ve Varsayılan Yapıcı Parametresi Girme

{% content-ref url="/pages/-MESX07n0DQnAFq9Ga2f" %}
[Fonksiyonlar](/boeluem-2-islem-yapma/fonksiyonlar)
{% endcontent-ref %}

Fonksiyonlar konusunda gördüğümüz gibi parametrelere değer yollarken hangi değişkene yollayacağımızı seçebiliriz.

```dart
class insan {
  String isim;
  int yas;
  double kilo;

  insan({String isim = "Kaan", int yas = 23, double kilo = 78.2}) {
    this.isim = isim;
    this.yas = yas;
    this.kilo = kilo;
  }
}

main() {
  insan kisi1 = new insan(isim: "Erkay", kilo:78.2);
}
```

`main` fonksiyonuna baktığımızda,

`kisi1` adında insan nesnesi oluştururken yapıcı fonksiyona sadece `isim` ve `kilo` değerlerini yolladık. `yas` değişkeninin değeri yapıcı fonksiyonda varsayılan değer aldı.

## İsimlendirilmiş Yapıcılar

Eğer sınıfımıza birden fazla yapıcı eklemek istiyorsak isimlendirilmiş yapıcıları kullanırız. Örnek:

```dart
class insan {
  String isim;
  int yas;
  double kilo;
  insan(this.isim, this.yas, this.kilo);

  insan.bos() {
    this.isim = "Boş";
    this.yas = 0;
    this.kilo = 0;
  }
}

main() {
  insan kisi1 = new insan.bos();
}
```

`insan` sınıfımız hem `insan` adlı yapıcı fonksiyona sahip, hem de `insan.bos` adında isimlendirilmiş yapıcı fonksiyona sahip. `insan.bos` yapıcı fonksiyonumuz `insan` sınıfından üretilen nesnede kullanıldığında değişkenlere boş bilgiler giriyor.

`main` fonksiyonumuzda nesne üretimini gözlemlediğimizde, nesnenin `insan.bos()` yapıcı fonksiyonu ile üretildiğini görüyoruz.


# Sınıf-içi Fonksiyonlar

Bir önceki konuda sınıf oluştururken insan üzerinden örnek vermiştik. Yine aynı örnek üzerinden gidelim.

{% content-ref url="/pages/-MEXM1zlUIN5d0b2Bj9i" %}
[Sınıflar](/boeluem-3-nesne-tabanli-programlama/siniflar)
{% endcontent-ref %}

`insan` sınıfımıza bir özellik *(yani fonksiyon)* ekleyelim. Bu özelliği tıpkı gerçek bir insanda bulunan kendini tanıtabilme yeteneği olsun.

```dart
class insan {
  String isim;
  int yas;
  double kilo;

  insan({String isim = "Kaan", int yas = 23, double kilo = 78.2}) {
    this.isim = isim;
    this.yas = yas;
    this.kilo = kilo;
  }

  void kendiniTanit() {
    print("Merhaba, Ben " + this.isim);
  }
}

main() {
  insan kisi1 = new insan(isim: "Erkay", kilo: 78.2);
  kisi1.kendiniTanit(); //Merhaba, Ben Erkay
}
```

`insan` sınıfımızın içerisine `kendiniTanit` adında bir fonksiyon ekledik. Fonksiyonumuz bir değer döndürmediği için tipini `void` yaptık. `print` fonksiyonu ile ekrana `this.isim` ile nesneye özel olarak kendini tanıtacağı bir cümle bastırdık.

`main` fonksiyonu içerisinde de, `kisi1` adında bir insan nesnesi oluşturduk ve içerisine yapıcıya gidecek olan parametre değerlerini girdik. Hemen aşağısındaki koda dikkat edelim. `kendiniTanit` fonksiyonu `insan` sınıfına ait olduğu için ve `kisi1` nesnesi de `insan` sınıfından türetildiği için `kendiniTanit` fonksiyonunu `kisi1` nesnesine iliştirdik.


# Sınıflarda Kalıtım (Inheritance)

Bir sınıfa ait özellikleri başka bir sınıfta da kullanmak istiyorsak kalıtım özelliğinden faydalanabiliriz. Örnek:

```dart
class insan {
  String isim;
  int yas;
  double kilo;
}

class calisan extends insan {
  double maas;
}
```

`insan` adında bir sınıf oluşturduk ve bir insanda olacak özelliklerden referans alarak değişkenler oluşturduk.

`calisan` adında bir sınıf oluşturduk ve `extends insan` yazarak `insan` sınıfının özelliklerinden faydalanmasını sağladık. Sonuçta çalışanlar da bir insan 😉

Bir çalışanın özelliği olan maaş (`maas`) özelliğini ekledik. Yukarıdaki örneğimizde `calisan` sınıfı `insan` sınıfının özelliklerine de sahip olacaktır.

## Kalıtım İşleminde Yapıcı Fonksiyon Nasıl Kullanılır?

Şöyle uzun bir kod örneği görelim:

```dart
class insan {
  String isim;
  int yas;
  double kilo;
  insan(String isim, int yas, double kilo) {
    this.isim = isim;
    this.yas = yas;
    this.kilo = kilo;
  }
}

class calisan extends insan {
  double maas;

  //Yapıcı Fonksiyonumuza dikkat edin
  calisan(isim, yas, kilo, this.maas) : super(isim, yas, kilo);
  kendiniTanit() {
    print("Ad: " + this.isim);
    print("Yaş: " + (this.yas).toString());
    print("Kilo: " + (this.kilo).toString());
    print("Maaş: " + (this.maas).toString());
  }
}

main() {
  calisan kisi1 = new calisan("Kaan", 23, 78.2, 3400.25);
  kisi1.kendiniTanit();
}
```

Yine bir `insan` sınıfı oluşturduk. Bu sınıf her zaman ki gibi bir yapıcı fonksiyona sahip.

`calisan` sınıfı oluşturduk ve bu sınıfı `insan` sınıfından miras aldık.  `calisan` adlı yapıcı fonksiyonumuza dikkat ettiğimizde,

Parametreler içerisine `isim`, `yas` ve `kilo` isminde parametreler aldık. Bu parametreler miras aldığımız sınıftan geldiği için türlerini belirtmedik. Son parametremiz ise `this.maas`. `maas` değişkenini **this** ile kolayca atadık. Parametrelerin yanındaki `super` fonksiyonu ise miras aldığımız sınıftan gelen parametrelerdir.

Daha sonra `kendiniTanit` fonksiyonu oluşturarak `calisan` sınıfına ait bilgileri ekrana yazdırmasını sağlayan bir fonksiyon oluşturduk.

### Kalıtım İşleminde İsimli Yapıcı Fonksiyon Kullanma

Nasıl yazacağımızı görelim:

```dart
class calisan extends insan {
  calisan() : super.bos();
  // ···
}
```


# Static

Sınıf yapısını oluşturuyorken, bazı nesnelerin dışarıyla olan etkileşimini ayarlamak gerekebilir.

`Static` ile oluşturulan değişken ve fonksiyonlara sınıf dışından erişilemezler. Örnek;

```dart
class insan {
  static String isim;
  
  static fonksiyonum() {
    print(isim);
  }
}
```

Yukarıdaki **insan** sınıfında **static insan** değişkeni oluşturduk. Bu değişken sadece sınıf içerisindeki işlemlerde kullanılabilecek. Aynı şekilde `fonksiyonum` 'da.


# Get ve Set Fonksiyonları

`Get` ve `Set` değişkenler üzerinde işlem yapabilmemizi sağlayan basit fonksiyonlardır. **Get** fonksiyonumuz değer döndürür. **Set** fonksiyonumuz da değer atar.

```dart
class insan {
  String kisiIsim;

  String get isim {
    return kisiIsim;
  }

  void set isim(String i) {
    this.kisiIsim = i;
  }

  insan(this.kisiIsim);
}

main() {
  insan kisi1 = insan("Kaan");
  print(kisi1.isim); //get işlemi
  kisi1.isim = "Erkay"; //set işlemi
}
```

Yukarıdaki kodları incelediğimizde;

{% hint style="info" %}
Farkettiyseniz **kisi1** nesnesini oluşturuyorken **new** terimini kullanmadık. Bu terim **Dart 2.2** beri zorunlu değildir.
{% endhint %}

\
`insan` sınıfımızın içinde `String get isim` ile **String** tipinde değer döndüren bir fonksiyon oluşturduk. Bu fonksiyonumuz **get** fonksiyonu olduğu için parametreler için paranteze sahip olmayacaktır. **get** fonksiyonumuz `kisiIsim` değerini döndürüyor.

**set** fonksiyonumuz ise `void`'tir. Çünkü bir değer döndürmez. **get** ve **set** fonksiyonlarının isimleri aynı olmak zorundadır. **set** fonksiyonu atama işlemi yapacağı için parametre alır.

`main` fonksiyonuna baktığımızda, `kisi1` adında `insan` nesnesi örneği oluşturduk. `print` fonksiyonu içerisinde `kisi1.isim` yazarak **get** işlemi yaptık. Hemen aşağısında `kisi1.isim = "Erkay";` yazarak **set** işlemi yaptık.

{% hint style="warning" %}
Set işlemi yapılırken parametre parantezi açılmaz. Değer atama şeklinde yapılır.
{% endhint %}

{% hint style="danger" %}
**Yanlış:** `kisi1.isim("Erkay");`
{% endhint %}

{% hint style="success" %}
**Doğru:** `kisi1.isim = "Erkay";`
{% endhint %}


# Asenkron Programlama Neden Önemlidir?

Asenkron işlemler, başka bir işleminizin bitmesini beklerken programınızın çalışmasına izin verir. Örnek işlemler şunlardır:

* Ağ üzerinden veri çekilirken,
* Veritabanı okunurken ve yazılırken,
* Bir dosyanın okunması,
* İndirme ve yükleme işlemi yapılırken

Bu yüzden asenkron programlama, bir program yazarken çok kullanılan bir özelliktir.


