Yeni başlayanlar için Dart Programlama Dili Temelleri

Soğuk,yağışlı bir kış gününden herkese merhabalar 🙂

Ben bir C# sevdalısı olarak farklı bir dili öğrenmeye karar verdiğim bir sürece giriş yapmış bulunuyorum. Bilirsiniz yeni yıl,yeni hedefler, yeni bir ben… Bu yıl hedefimde daha önce hiç deneyimlemediğim Flutter ve Go’yu öğrenip belirli bir seviyeye gelmek, hali hazırda kullandığım React.js ve C#’ da ise Darth Vader seviyesine gelme amacım, isteğim ve motivem(inşallah) var. Bu isteklerimden ilki olan Flutter için kolları sıvadım ama Flutter’a kavuşmak için Dart programlama diline hakim olmam gerekiyor. Şanslıyım ki Dart programlama diline başladığım ilk akşamda; benim kuşum olmamasına rağmen Visual Studio Code’u her açtığımda bilgisayara konan,bence yazılıma ilgisi olan ‘Bambam’ yanımdaydı. Bence kendisi bu yazının kapağı olmayı haketti, sizce ?

Neyse…

Ben Dart programlamanın temellerini az biraz öğrenebildiğimi düşünüyorum. Tabii bazı syntaxlar kafamı karıştırmadı mı karıştırdı ama pratik ve tekrar ile oturacağını düşünüyorum. Bu farklı deneyimde de çalıştığım konu ve başlıkları da not halinde sizlerle paylaşmak istedim. Şimdiden faydalı olması dileklerimle 🙂





Dart Nedir?

Flutter geliştirebilmek için Dart dilini bilmek gerektiğinden bahsetmiştim. Bunun sebebi aslında mantıksal olarak çok basit. Android -> Java, Swift -> Objective-C , React Native -> Js, Xmarin -> C# ‘tan geldi. Flutter da benim ne eksiğim var diyerekten nedir yani ben de Dart’tan gelirim demiş. Baktığınızda bu diller bilindik olduğu için herkes bunlara yönebilir ama Flutter maalesef değil. Altyapısında Dart bulunuyor. O nedenle belki de mobil programlamaya yönelmek isteyen bir Full Stack Developer, bu durumdan biraz korkabilir. Eğer profesyonel olarak Java ile uğraşıyorsa Android yazmayı tercih edebilir. Halbuki Flutter daha avantajlıdır. Ek olarak Flutter Framework, cross platform development ortamı da sağlar. Projelerimizde Flutter gücüyle Ios,Android,Mac web, Macos gibi çeşitli uygulamalar geliştirilebilir.( tek bir single kod ile) . İşi yapan kısım Dart, ( telefon derlenmesi,esnekliği sayesinde ), derlenmesi(cross platform) sayesinde çok rahatlıkla uygulamalara, telefonlara ve clientlara eklenebilir. Dart, core gücünü burada fazlasıyla hissettirmektedir. Ek olarak sadece Flutter ile ilgili değil,backend projelerinde de Dart programlama dilini kullanılabilir.

Dart’ın Geçmişi

2009 yılında Internal, 2013 Open Source, 2016 da tamamen kullanıma açılmış bir programlama dilidir. Dart; JS konseptiyle başlamış, şimdilerde ise Object Oriented’a uyumlu bir dil haline getirilmiştir. Baktığınızda Dart, bütün dilleri içeren anlaması kolay bir dildir.

Google tarafından geliştirilmiş olan, esnek, öğrenmesi kolay bir dildir. Sektörün verdiği örnekleri biliyorsanız, deneyimlediyseniz rahatça kullanabileceğiniz bir dildir. Ayrıca Dart VM sayesinde yazdığımız kodlar derlenir ve makinede görebiliriz.

Dart.Dev

Detaylı kurulum ve dil ile ilgili detaylar için aşağıdaki web sitesini ziyaret edebilirsiniz.

Dart programming language
Google uses cookies to deliver its services, to personalize ads, and to analyze traffic. You can adjust your privacy…dart.dev

Kurulum

Kurulum için herhangi bir build ve compile işlemine gerek bulunmamaktadır. Sadece bilgisayara Dart’ın yüklemesinin yapılması şarttır. Eğer yükleme yapmak istemiyorsanız Dart.Pad’i kullanabilirsiniz. Bu IDE üzerinden online olarak Dart ile ilgili çalışmalar gerçekleştirebilirsniz.

Dart.pad online tool

Kurulum için Dart’ın kendi sitesinde farklı kurulum yöntemleri var ama ben şu şekilde bir yol izledim.

Ziplerin bulunduğu alan

Bu alan seçildikten sonra indirilen zip ayıklanarak içerisinde gelen dart-sdk dosyası C:/ ‘nin altına yapıştırılır. Sonrasında Environment Variables tarafındaki path alanına aşağıdaki gibi eklenir.

Environment Variables alanı

Vee ta daa Dart bilgisayarımıza yüklenmiş oldu.

Dart versiyonunu kontrol edebileceğiz alan

Editör olarak ben Visual Studio Code kullandım. Öneri olarak Intellij Idea de kullanabilirsiniz.

Dart ile ilgili kullanabileceğiniz VS Code Eklentileri

Aşağıda Dart programlama dilini kullanırken ekleyebileceğiniz eklentileri sıraladım.

  • Dart
  • Dart ( Syntax Highlighting Only)
  • Dart Barrel Export File Genarator
  • Dart Data Class Generator
  • Dart Exports
  • Dart-Import

Main Fonksiyonu

Dart projesinin başlangıç noktası main’dir. Eğer .dart dosyasında bir fonksiyon yazıp adına da main derseniz bu bizim dart projesinin başlangıç noktası olur. Main içerisine yazdıklarınız doğrudan derlenip compile edilip sonuç döndürür. Main fonksiyonu içerisinde bir argüman almasına gerek kalmadan çalışabilir. Kodlamaların hemen hemen hepsinde başlarken bir “Hello World” dediğimiz için gelin klasiği bozmayalım. 🙂 Yaptığımız bu çıktıyı ekranda görmek istersek IDE üzerinden Run da diyebiliriz. Terminal üzerinden dart dosya_dizini dersek sonucu bize döndürür. Ki bence Dart programlama diliyle Visual Studio Code üzerindeki debug işlemleri mükemmel!

void main(params) {
print("Hello World");
}
Run/Debug işlemlerinin yapıldığı alan
dart week1/start.dart

Print yapısı debug için de kullanılabilir. Bir value bulunuyor mesaj vermek istiyorum, print bu mesajı konsol üzerinde gösterir. Bunu Flutter tarafında da kullandığımızda farklı yapılar kullanabiliriz. Basitçe ekranda bir şey göstermek istiyorsak print fonksiyonu kullanılır.

Veri Tipleri

Yazılımın en temel noktasıdır ve birçok veri tipi bulunmaktadır. Başlangıç oalrak iki tanesine odaklanacak olursak, ekranda bir string mesaj oluşturacaksam yani örneğin 10 tane Hello World yazdıracaksam alt alta 10 tane print yazınca işlemi gerçekleştirmiş olabilirim ama bir yerlerde yanlış yapıyorum demektir. Çünkü aynı data ve veriyi sürekli yazıyorum. Bunu ortaklaştırma veri değişikliğini kontrol etme noktasında veri tipleri devreye girer. Veri tipleri verileri saklama ve yönetme imkanı sunar. Bu sayede efektif kodlar yazılabilir. Bir veri tipi tanımlanacak ise aşağıdaki gibi tanımlanabilir. Bu sayede eğer hello değişkeninin değerini değitirirsek print içerisinde basılan değer de otomatik olarak değişecektir.

String valuableName = "valuable";
String hello = "Hello61";
int number = 15;

print(hello);
print(hello+number); -> Yanlış kullanım string ile int toplanmaz.!
print(hello+number.toString());
print(hello + '$number');
print(hello + ' ' + '$number');

Uygulama 1

  • Müşterinin adını, soyadını tutacak.
  • Müşterinin parasını öğren.
  • Müşteriye Merhaba diyerek para bilgisini verebilecek.
  • Bankayı seçtiği için parasına +10 tl ekle.
void main(params) {
//Kullanıcının adı tutuldu.
String customerName = "Kardel Ruveyda Cetin";
// Kullanıcının parası tutuldu.
int customerMoney = 30;
//Kullanıcının username alanı tutuldu.
String username = "kardelruveyda";
//Bankayı seçtiği +10 ekleme yapıldı.
customerMoney = customerMoney+10;

//Konsola yazdırıldı.
print("Merhaba $username, son durumda paranız $customerMoney olarak güncellenmiştir.");
}

Uygulama 2

  • Yeni bir user adı oluştur.
  • Yeni bir para değeri ata.
  • Bu parayı 20’ye böl ve ekranda göster.
void main(params) {
//Yeni bir user tanımlandı.
String userName = "kardelruveyda";
//Para tanımlandı.
int userMoney = 250;
//Para 20'ye bölündü.
userMoney = userMoney ~/20;
print("Merhaba $userName, güncel paran : $userMoney");
}

Dart dilinde double bir değeri int değere çevirmek için “ ~ “ kullanılır. Veya toInt() fonksiyonunu da kullanabilirsiniz. Birçok dilde olduğu gibi Dart diinde de dynamic tanımlama da mevcuttur. “var” sözcüğü kullanılarak dynamic bir atama yapılabilir. Dynamic olarak atama yapıldığında bu değişken farklı bir durumda değişebilir. Eğer bir değişken atandıktan sonra onn değiştirilmemesi ve işlem yapılmamasını istiyorsanız “final” yapısını kullanmanız gerekir. Bir nevi kodu sabitlemiş ve değiştirilemez hala getirebilirsiniz. Ek olarak “const” yapısını da kullanabilirsiniz. Final ve Const arasındaki fark, Final uygulama çalıştığında run time alanındaki son değeri alır. Run time da çalışmak şu anlama gelir; uygulama çalıştı, telefonda ekran gözüktü . Merhaba bankaya hoşgeldiniz. time değeri gibi o an çalışan değeri gösterir. Bu sayede o an gelebilecek bir değer bu yapıya verilebilir. Const ise proje başlarken veya proje compile olduktan sonra direkt neyse o gözükür. Ekranda değişme imkanı olmaz. Final’ın da tabii olmaz ama final, initialize değerini ekran geldiğinde alabilir.

void main(params) {
//Normal tanımlama
String userName = "Kardel";
//Sonra değiştirlemeyecek bir variable
final bankMoney = 10;
//Dynamic atama
var userName2 = "veli2";
print(userName);
print(userName2);
}

Conditions

If Else

Object Oriented dillerle daha öncden çalışmış biri olarak Dart dilindeki if else yapısını kullanırken pek yabancılık çekmedim. Diğer diller ile benzer bir yapıda olduğunu söyleyebilirim. Örneğine aşağıdan ulaşabilirsiniz.

void main(params) {
bool isActive = false;
final int money = 15; if (isActive) {
print("Kullanıcı aktif!");
} else {
print("Kullanıcı aktif değil!");
}

if(money > 15){
print("Fiyatı pahalı!");
}else {
print("Fiyatı ucuz!");
}
}

Switch Case

Switch case yapısını test edebilmek için şöyle bir örnek yapalım ;

  • 1 ise kötü
  • 2 ise geliştirebilir
  • 3 ise iyi
  • 4 ise çok iyi
  • Eğer bunlardan hiçbirine uymuyorsa o zaman da “başarısız” dönüşü verecek verecek bir yapı yazalım. ( Normalde bunu if else mantığı ile de yazabilirsiniz. ) Ancak switch case if’e göre daha performanslıdır. (Bu detayı da unutmamak lazım.)

Switch case içerisinde verilen değerin “final” olmasına dikkat edilmelidir.

void main(params) {
final int degree = 2;

switch(degree){
case 1 :
print("kötü");
break;
case 2 :
print("geliştirebilir");
break;
case 3:
print("iyi");
break;
case 4 :
print("çok iyi");
break;
default:
print("başarısız");
break;
}
}

Operators

Operatorlerin yapısını anlayabilmek için aşağıdaki örnekleri inceleyebilirsiniz.

void main(params) {
//Değişken tanımlanır.
int money = 5;

// 5 arttırdık
money = money + 5;
// 1 arttırdık
money += 1;
money++;

String name = "Kardel";
String surname = "Çetin";

// + operator sayeside iki string yan yana yazılır.
print(name + surname);

//Karşılaştırma Operatörleri
// "=="
if (name == "Kardel") {}
//!=
if (name.length != 2) {}
//<=
if (name.length <= 2) {}
//>=
if (name.length >= 3) {}

// Kalan çift mi tek mi?

int myMoney = 28;
print(myMoney % 2 == 0 ? "Çift" : "Tek");

// Dart ile gelen hazır yapılar kullanılabilir. isEven ve isOdd
print(myMoney.isEven);
print(myMoney.isOdd);
}

Lists

Listelerin yapısını anlayabilmek için aşağıdaki örnekleri inceleyebilirsiniz.

void main(params) {
List<int> moneys = [100, 110, 50];

// Birinci müşteri parası

print('Birinci müşteri parası : ${moneys[0]}');

//Para birimlerini parası büyük olana göre sırala.
moneys.sort();
//5 tl de eklensin. 5 tl listenin en başına eklenir.
moneys.add(5);
//sona eklemek istersem.( tolist() dendiği an yeni bir liste yeni bir data set oluşmuş olur. )
print(moneys.reversed.toList());
// Spesifik bir alana eklemek istiyorsam;
moneys.insert(2, 250);
//tersine çevirme işlemi ise
moneys.reversed.toList();

print(moneys);

//Listeler referans olduğu için
//Final yaptığınızda nesne olarak değiştirilemez olsa da listenin içerisindeki neslere dokunup değiştirip işlem yapılabilir.
final List<int> newMoneys = [200, 300, 400, 500];
newMoneys.add(5);
//Listenin içerisi temizlenir.
newMoneys.clear();
print(newMoneys);
}

Döngüler

Döngülerin yapısını anlayabilmek için aşağıdaki örnekleri inceleyebilirsiniz.

void main(params) {
List<int> moneyCustomerNews = [100, 30, 60, 50];
// For Yapısı. İki çeşiti vardır for ve for in
moneyCustomerNews.sort();
for (var i = 0; i < moneyCustomerNews.length; i++) {
print('müşteri parası : ${moneyCustomerNews[i]}');

if (moneyCustomerNews[i] > 45) {
print("Zenginsin!");
} else {
print("Fakirsin!");
}
}
}

Methods

Metotların yapısını anlayabilmek için aşağıdaki örnekleri inceleyebilirsiniz.

void main(params) {
controlUserMoney();
controlUserMoneyWithParameter(5);
controlUserMoneyWithMinimumValue(3, 2);
convertToStandartDolar(1500);
convertToStandartDolar(2500, dolarIndex: 12);
convertToEuro(userMoney: 800);
}

//parametresiz bir metot
void controlUserMoney() {
final int userMoney = 0;

if (userMoney > 0) {
print('Kullanıcının bankada parası var.');
} else {
print('Kullanıcının bankada parası yok.');
}
}

//parametreli bir metot

void controlUserMoneyWithParameter(int money) {
if (money > 0) {
print('Kullanıcının bankada parası var.');
} else {
print('Kullanıcının bankada parası yok.');
}
}

void controlUserMoneyWithMinimumValue(int money, int minumumValue) {
if (money > minumumValue) {
print('Kullanıcının bankada parası var.');
} else {
print('Kullanıcının bankada parası yok.');
}
}

// Dolara çeviren metot aşağıdaki gibidir.
int convertToStandartDolar(int userMoney, {int dolarIndex = 19}) {
return userMoney ~/ dolarIndex;
}

int convertToEuro({required int userMoney, int dolarIndex = 19}) {
return userMoney ~/ dolarIndex;
}

Lists Advanced

Aşağıdaki örneklerde listenin dynamic tipine değinilmektedir. Buradaki tipte listeye int,string, boolean gibi değerler atayabilirsiniz ama kullanım açısından çok tercih edilmemelidir. Çünkü karışık bir dizi sonradan başımıza bela olabilir. String, Integer diziler oluştursak sanki daha iyi olur gibi. 🙂

void main(params) {
// çok tavsiye edilmez.
List<dynamic> dynamicList = [1, 'a', true];

for (var item in dynamicList) {
print(item);
}

List<String> userNames = ['kardel', 'ruveyda', 'cetin'];

print(userNames.contains('kardel')
? 'Dizide bulunuyor.'
: 'Dizide bulunmuyor.');

// for in nasıl çalışır?
// performans olarak contains tabii ki daha avantajlıdır.
for (var element in userNames) {
if (element == 'kardel') {
print('Dizide bulunuyor');
} else {
print('Dizide bulunmuyor.');
}
}
}

Maps

Yazılım dünyasında en çok kullanılan yapılardan biri de Map’tir. Tabii diğer yazılım dillerinde popüler olduğu gibi Dart dilinde de populer bir kullanımdır. Map tarafında birinci parametre key, ikinci parametre ise value olarak tanımlanır. Daha iyi anlayabilmeniz için aşağıdaki notlarla kodu incelemenizi tavsiye ederim. 🙂

void main(params) {
Map<String, int> users = {'kardel': 50, 'ruveyda': 60, 'cetin': 80};

//Burada ${users['kardel']} "users" daki alanda "kardel" keyinin karşılığı olan valueyi verir.
print('kardelin parası ${users['kardel']}');

print('-------------------------');
// Buradaki örnekte users içerisindeki keyler içerisinde dönülür.
// Döndükçe ${item} ile keyin adı, ${users[item]} ile de keyin valuesi yazdırılır.
for (var item in users.keys) {
print('${item} - ${users[item]}');
}

print('-------------------------');

// Buradaki mantık da aynıdır.
// Ancak usersın lengthi içerisinde dönüldüğü için elementAt fonksyonu kullanılarak keys ve valuesler yazdırılır.

for (var i = 0; i < users.length; i++) {
print('${users.keys.elementAt(i)} - ${users.values.elementAt(i)}');
}
print('-------------------------');

//maplerde müşteriler olsun, müşterilerin birden fazla hesabı olabilir.
//kardel'in üç hesabı var 100,200,300
//ruveyda iki hesabı var 50,60,70

// Müşterilerin hesaplarını kontrol et, herhangi bir hesapta 100 tl den fazladan olan varsa krediniz hazır diyebilirsin.
print('------------------------------');

// Mapleme işlemi aşağıdaki gibi bir şekilde tanımlanmıştır.
// Burada her müşterinin birden fazla hesabı bulunmaktadır.
final Map<String, List<int>> kardelBank = {
'kardel': [100, 200, 300],
'ruveyda': [50, 60, 70]
};

// Maps işlemine aşağıdaki gibi bir yazımla yeni müşteri ekleyebilirsiniz.
kardelBank['cetin'] = [40, 50];

// öncelikle kardelBank nesnesindeki keysler içerisinde dönülür.
for (var item in kardelBank.keys) {
//bankanın tüm elamanları
//sonrasında bu kardelBank'a bu itemların değeri verildiğinde geri dönüş değeri liste olduğu için bir for döngüsüne daha ihtiyaç vardır.
for (var money in kardelBank[item]!) {
if (money > 100) {
print("Kredin hazır!");
break;
//burada eğer koda devam etmeyecekseniz return diyebilirsiniz.
//devam edecekseniz break demelisiniz. break sadece bu scope özelinde return yapar
// aşağıdaki kodun çalışmasını etkilemez.
}
}
}

// müşterilerin tüm hesaplarındaki toplam mebla
print('--------------------------');
for (var item in kardelBank.keys) {
int result = 0;
for (var money in kardelBank[item]!) {
result += money;
}
print('${item} senin toplan paran -> $result');
}
}

Class Yapısı ve Null Püf Noktaları

  • Her classın bir objesi olabilir.
  • Class içerisinde özellikler tanımlanır.
  • Dart dili baştan sona Object Oriented ve nesneleri koruyan bir dildir.
  • Önceki örneklerde hep değişken tanılayıp bu değere bir value vermiştik. Ancak değişken atamadıysam Dart dilinde bu değer null olarak atılır ve Dart bunu kullandırtmaz. Eğer bir nesne kullanıyorsanız int,string bunların ne olduğunu bana söylemeniz gerekir mantığında çalışır.
  • Dart dilinde hiçbir nesneyi boş olarak tanımlayamayız. Eğer tanımlamak istiyorsak soru işareti ile atanabilir.
void main(params) {
// Yanlış Kullanım
int newMoney;
//Doğru Kullanım
int? newMoney
}
  • İlerleyen projelerde Dart tarafında servisler yazmanız gerkebilir. Bu servisler içerisinde data vs çekme durumu olacak ve bununla ilgili işlemler yapmaya başlayacaksınız. Servise istek attığınızda her zaman yanıt döneceği kesin değildir. Bu gibi durumlarda verinin geleceğinden emin değilsek soru işareti atıp bu data null gelebilir şeklinde tanımlayabiliriz.
  • Değikeni nullable şeklinde atasam bile print(newMoney + 10 ) dersem çalışmaz. Çünkü null gelebilecek bir yazılım olduğu için hata alır.
  • Genelde newMoney!+10 şeklinde bir yazım kullanıldığını görebilirsiniz. Ancak kullanılması gereken en son tercihtir. Ben bu nesnenin kesin dolu gelecek gibi düşünülmesine neden olabilir ama dolu geleceği kesin değildir. Bir nevi yalan söylemiş oluruz. Bu da hoş olmaz. 🙂
  • Nullable olarak tanımlanmış bir değişkene veri ekleyebilmek için nullable kontrolü yapıp ekleme gerçekleştirilmelidir.
  • Nullable demek bu nesnenin hiç olmayacağı anlamına gelir.
void main(params) {
int? newMoney;
if (newMoney != null) {
print(newMoney + 40);
} else {
print(10 + 20);
}
}

Bir örnek yapalım;

  • Bankaya 3 tane müşteri gelsin. Birinin 50 TL’si var, diğerinin hesabı yok, bir başkasının ise 0′ TL’si var. Hesabı olmayana hesap açalım, 0 Tl’si olana kredi verelim. 50 tl si olana hoşgeldiniz yazalım.
  • Hesabı yok demek sıfır demek mi? Hayır! Bu nullable anlamına gelir. Ancak liste oluştururken eğer integer bir liste oluşturuyosanız listenin tam sayı olduğunu söylediğiniz için liste içerisinde null bir değer verirseniz hata alırsınız. List<int> customers = [50,null,0] hatalı bir yazılımdır. int? olarak kullanırsanız bu listenizde nullable bir değer olabileceğine işarettir ve doğrudur.
List<int> customers = [50,null,0]; // Hatalı 
List<int?> customers = [50,null,0]; // Doğru

Class yapısındaki örneklere aşağıdaki kod örneklerinden detaylıca ulaşabilirsiniz.

Dart dilinde bir diğer önemli nokta “late” kavramıdır. Burada nesnenin başlangıçta bir değeri yoksa ve nullable olma durumu var ise late kavramının sürekli olarak kullanıldığı karşımıza çıkmaktadır. Late değişkenin ilk başta bir anlamı ve değeri olmasa da initialize edildiğinde olacağı anlamını taşır. Aşağıdaki kod dizininde Customer2 örneğindeki gibi eğer bazı alanlar null geçilebilir alanlarsa bu alanlar {} içine alınır. Böylece bu alanlara herhangi bir değer verilmese de sıkıntı olmayacaktır. Ayrıca null olduğunu bildiğimiz değerler ile null olmayan bazı değerleri birleştirecek işlemler yapacaksak da mutlaka nullable kontrolü yapmamız gerekir. Bunu basitçe ?? operatörü ile gerçekleştirebiliriz.

void main(params) {
CustomerClassCheck();
}

class Customer {
late final String name;
late final int money;
late final int age;
late final String city;

Customer(String name, int money, int age, String city) {
this.name = name;
this.money = money;
this.age = age;
this.city = city;
}

//Değişken gelecek ve constructor tarafında doldurulacak ise late yapısı kullanılabilir.
//İlk başta bir anlamı değeri yok, intialize edildiğinde olacak.
}

class Customer2 {
//age ve city alanları zorunlu alanlar değiller.
late final String name;
late final int money;
late final int? age;
late final String? city;

// aşağıdaki gibi {} içine alıp yazdığımızda bu alanları değer olarak vermek zorunda olmadığımız görülür.
Customer2(String name, int money, {int? age, String? city}) {
this.name = name;
this.money = money;
this.age = age;
this.city = city;
}
}

class Customer3 {
late final String name;
late final int money;
late final int? age;
late final String? city;
// sürekli final vermek zorunda değilsiniz.
// bu değişken sonradan gelecek. Late derseniz herhangi bir zamanda verebilirsiniz.
// late dolmadan, değer dolmadan önce çağırırsanız hata alabilirsiniz.
// late final kullanırsanız yüzde yüz olarak constructor da kullanmak gerekiyor.

late final String userCode;
// aşağıdaki gibi {} içine alıp yazdığımızda bu alanları değer olarak vermek zorunda olmadığımız görülür.
Customer3(String name, int money, {int? age, String? city}) {
this.name = name;
this.money = money;
this.age = age;
this.city = city;
userCode = (city ?? 'tr') + name;

// ?? kontrolü yaparak kullanılabilir.
}
}

void CustomerClassCheck() {
Customer customer = Customer('test', 0, 5, 'istanbul');
Customer2 customer2 = Customer2("test", 0);
Customer2 customer3 = Customer2("test", 0, age: 12);

print(customer.age);
print(customer2.age);
print(customer3.age);
}

Extends etmek ve Abstract Class

Her yazılımda olduğu gibi Dart programlama dilinde de extend etmek ve abstract class kavramı bulunmaktadır. Abstract class kullamında en önemli ihtiyaç, tekrarlanan alanların ortak bir alanda toplanarak diğer classlar tarafından çağırılmasını sağlamaktır. Dart programlama dilinde de bu kullanım aşağıdaki kod bloğunda bu örnekler detaylıca gösterilmiştir.

void main(params) {
final userNormal = User('kardel', 15);
userNormal.sayMoneyWithCompanyName();
}

abstract class IUser {
final String name;
final int money;

IUser(this.name, this.money);
void sayMoneyWithCompanyName() {
print('Kardel - $money paranız var');
}
}

class User extends IUser {
final String name;
final int money;

User(this.name, this.money) : super(name, money);
}

class BankUser extends IUser {
final String bankingCode;

BankUser(String name, int money, this.bankingCode) : super(name, money);
}

class SpecialUser extends IUser {
final String bankingCode;
final String discount;

SpecialUser(String name, int money, this.bankingCode, this.discount)
: super(name, money);
}

Implements

Implements kavramı abstract classa göre biraz farklıdır. Burada implements edilen class ile alt sınıflar birebir aynı olacak şekilde ayarlanır. Zaten bir implement yapısını kullandıktan sonra farklı bir class içerisinde bu metotu implemente ederseniz ve metotun içerisini temizlerseniz, otomatik olarak override işlemi gerçekleştirebilirsiniz. Ek olarak abstract classlarda kullandığınız “super” kavramını burada kullanmanıza gerek yoktur. Aşağıdaki kod bloğundan detaylıca inceleyebilirsiniz.

void main(params) {}

abstract class IStudent {
final String name;
final int age;

void saySomething() {
print(age);
}

IStudent(this.name, this.age);
}

class Student implements IStudent {
final String name;
final int age;

Student(this.name, this.age);

@override
void saySomething() {
// TODO: implement saySomething
}
}

class Student2 {
final String name;
final int age;

Student2(this.name, this.age);
}

Enums

Enumlar yazılım dillerinde oldukça kullanılan yapılardan biridir. Enum demek sınıflandırmak demektir. Detaylı örneği aşağıdaki kod bloğunda inceleyebilirsiniz.

void main(params) {
final color = Color.blue;
// numarası
print(color.index);
//ismi
print(color.name);
switch (color) {
case Color.blue:
print("mavi");
break;
case Color.red:
print("kırmızı");
break;
case Color.black:
print("siyah");
break;
case Color.white:
print("beyaz");
break;
}
}

enum Color { blue, red, black, white }
enum Color { blue, red, black, white }

Extension

Dart programlama dilinde ve özellikle Flutter ile mobil uygulama geliştiren yazılımcıların sıkça kullandığı özelliklerden biri de extension mantığıdır. Bu kullanımın fazlası karmaşaya yol açarken kararında kullanımı hayat kurtarabilir. 🙂 Aşağıdaki kod bloğunu incelediğinizde sıfırdan bir extension nasıl yazılır öğrenmiş olacaksınız. Ayrıca nullable ve nullable olmayan ayrımına göre de kod düzenlenmiştir.

void main(List<String> args) {
if('ali'.isAdmin()){
print('object');
}else {
print('no');
}

// eğer nullable olursa
String? name;
name.isAdmin();
}

// String? denmelidir nullable olursa
extension StringUserCheckExtension on String? {
bool isAdmin(){
// ?? nullable kontorlü yapılır.
return (this ?? '').toLowerCase() == 'admin'.toLowerCase();
}
}

Bu dile yeni başlayan biri olarak en çok nerelerde kafam karıştı :(?

  • Dart’ın null yapısında kafam hayli karıştı. Anladığma göre Dart bu null durumunu pek bir önemsiyormuş. Bu konuyla ilgili notlarıma arada bir bakmam gerekecek gibi.
  • Map yapısı birazcık kafamı karıştırdı ama sonradan C#’daki Dictionary yapısı ile bağdaştırınca bu kafa karışıklığım biraz olsun azaldı. ( Teşekkürler Hamza Ağar :))
  • Yalan söyleyemeceğim class yapısı da bir hayli kafamı karıştırdı. Özellikle şu late kavramı 😀 C#’ın gözünü seveyim,prop tab tab al sana mis gibi property 😀

Yeni başlayan biri olarak hiç kafamın karışmadığı noktalar?

  • Döngüler, değişken tanımlama, veri tipleri gibi işlemler açıkçası hiç kafamı karıştırmadı. Javascript ile C# ‘ın birleşimi bir dil gibi geldi.

Benim bugünlük anlatacaklarım bu kadar, bir sonraki yazıda görüşmek üzereee 🙂

Kodlara https://github.com/KardelRuveyda/dart-exercises buradan ulaşabilirsiniz. 🙂

Kaynakça

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir