Gereksinimler ve Ön Hazırlık
Java projelerinizi geliştirmek için sisteminizde güncel bir JDK (Java Development Kit) sürümünün kurulu olması gerekir. 2026 yılı itibarıyla Java 21 veya üzeri LTS (Long Term Support) sürümlerini kullanmanız önerilir.
- JDK: Java 21 veya daha yeni bir sürüm.
- IDE: IntelliJ IDEA, Eclipse veya VS Code (Java eklentisi ile).
- Temel Bilgi: Değişkenler, veri tipleri ve temel operatörler hakkında bilgi sahibi olmanız yeterlidir.
Kurulumu doğrulamak için terminal veya komut satırına java -version komutunu yazarak sisteminizin hazır olup olmadığını kontrol edebilirsiniz.
Adım 1: Kullanıcı Girdisi İçin Scanner Sınıfını Tanımlama
Java'da konsoldan veri okumak için java.util paketinde bulunan Scanner sınıfını kullanırız. Bu sınıf, kullanıcının klavyeden girdiği değerleri programımıza aktarmamızı sağlar.
import java.util.Scanner;
public class HesapMakinesi {
public static void main(String[] args) {
Scanner tarayici = new Scanner(System.in);
System.out.print("Birinci sayıyı girin: ");
double sayi1 = tarayici.nextDouble();
System.out.print("İkinci sayıyı girin: ");
double sayi2 = tarayici.nextDouble();
}
}
Yukarıdaki kod bloğu, kullanıcıdan iki adet ondalıklı sayı (double) alır. Scanner nesnesini oluştururken System.in parametresini kullanarak standart giriş akışını dinlemeye başlarız.
Adım 2: İşlem Seçimi ve Switch-Case Yapısı
Kullanıcının toplama, çıkarma, çarpma veya bölme işlemlerinden hangisini yapmak istediğini belirlemesi gerekir. Bunun için switch-case yapısı, okunabilirliği artırdığı için if-else bloklarına göre daha avantajlıdır.
System.out.println("İşlem seçin (+, -, *, /): ");
char islem = tarayici.next().charAt(0);
double sonuc = 0;
switch (islem) {
case '+': sonuc = sayi1 + sayi2; break;
case '-': sonuc = sayi1 - sayi2; break;
case '*': sonuc = sayi1 * sayi2; break;
case '/': sonuc = sayi1 / sayi2; break;
default: System.out.println("Geçersiz işlem!"); return;
}
Bu yapıda, next().charAt(0) metodu ile kullanıcının girdiği karakter dizisinin ilk karakterini alıyoruz. default bloğu, tanımlanmayan bir işlem girildiğinde programın hata vermesini engeller.
Adım 3: Hata Yönetimi ve Sıfıra Bölme Kontrolü
Yazılım geliştirmede en önemli kurallardan biri, kullanıcıdan gelen hatalı verileri öngörmektir. Matematiksel olarak bir sayının sıfıra bölünmesi tanımsızdır; bu durum Java'da "Infinity" (sonsuzluk) sonucunu döndürür. Bunu engellemek için kontrol mekanizması kurmalıyız.
if (islem == '/' && sayi2 == 0) {
System.out.println("Hata: Bir sayı sıfıra bölünemez!");
} else {
System.out.println("Sonuç: " + sonuc);
}
Bu kontrol, programın çalışma zamanında (runtime) beklenmedik sonuçlar üretmesini engeller. Kullanıcıyı bilgilendirmek, uygulamanın kullanıcı deneyimini (UX) doğrudan iyileştirir.
Adım 4: Uygulamayı Metotlara Bölerek Modülerleştirme
Kodunuzun karmaşıklaşmaması için her işlemi ayrı bir metotta toplamak, Java'da "Clean Code" (Temiz Kod) prensiplerine uygundur. Bu yaklaşım, ileride yeni matematiksel fonksiyonlar eklemenizi kolaylaştırır.
public static double topla(double a, double b) { return a + b; }
public static double cikar(double a, double b) { return a - b; }
public static double carp(double a, double b) { return a * b; }
public static double bol(double a, double b) { return a / b; }
Yukarıdaki metotlar, ana metot içerisindeki karmaşayı azaltır ve kodun tekrar kullanılabilirliğini sağlar. Her bir metot, iki parametre alarak işlemin sonucunu döndürür.
Adım 5: Gelişmiş Kullanıcı Deneyimi ve Döngü Kullanımı
Uygulamanın her işlemden sonra kapanması yerine, kullanıcının istediği kadar işlem yapabilmesi için bir while döngüsü ekleyebiliriz. Bu, uygulamanın daha profesyonel görünmesini sağlar.
boolean devamEt = true;
while (devamEt) {
// İşlemler buraya...
System.out.print("Devam etmek istiyor musunuz? (e/h): ");
char cevap = tarayici.next().charAt(0);
if (cevap == 'h') devamEt = false;
}
Bu döngü, devamEt değişkeni false olana kadar programı çalışır tutar. Bellek yönetimi açısından, döngü bittiğinde tarayici.close() komutuyla kaynakları serbest bırakmayı unutmayın.
Karşılaştırma: Hesap Makinesi Yöntemleri
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| If-Else Blokları | Basit mantıklar için hızlıdır. | Çoklu koşullarda okunabilirliği düşürür. |
| Switch-Case | Okunabilir ve temizdir. | Sadece belirli sabit değerlerle çalışır. |
| Metot Kullanımı | Modüler ve sürdürülebilirdir. | Küçük projelerde biraz "over-engineering" olabilir. |
Kritik Güvenlik Uyarısı: Konsol uygulamalarında kullanıcıdan alınan her veri "güvensiz" kabul edilmelidir.ScannerkullanırkenInputMismatchExceptiongibi hatalarıtry-catchblokları ile yakalamak, programın çökmesini (crash) engeller. Asla kullanıcı girdisini doğrudan sistem komutları gibi çalıştırmayın.
Sıkça Sorulan Sorular
Scanner sınıfı neden kapatılmalıdır?
Scanner sınıfı, sistem kaynaklarını (stream) kullanır. Program bittiğinde bu kaynağın serbest bırakılmaması bellek sızıntılarına (memory leak) yol açabilir. close() metodu bu kaynakları kapatır.
Neden double veri tipini tercih ettik?
Hesap makinesinde bölme işlemi gibi ondalıklı sonuçlar içeren işlemleri desteklemek için int yerine double kullanmak, sonuçların hassasiyetini korur.
Programım neden "InputMismatchException" hatası veriyor?
Kullanıcı sayı beklenen bir alana harf girdiğinde bu hata oluşur. Bunu engellemek için scanner.hasNextDouble() metodu ile verinin sayı olup olmadığını kontrol etmelisiniz.
Switch-case yerine neden if-else kullanmıyoruz?
Dört işlem gibi seçenekli durumlarda switch-case, kodun dallanmasını daha net bir şekilde gösterir ve performans açısından çoklu if bloklarına göre daha optimize çalışabilir.
Kodumu nasıl daha profesyonel hale getirebilirim?
Kodunuzu sınıflara ayırarak (OOP), kullanıcı arayüzünü konsoldan grafiksel arayüze (JavaFX veya Swing) taşıyarak veya hata yönetimini loglama kütüphaneleri ile geliştirerek profesyonelleştirebilirsiniz.
İleri Seviye İpucu: İşlem Geçmişini Dosyaya Kaydetme
Uygulamanızın profesyonellik seviyesini artırmanın en etkili yollarından biri, kullanıcı tarafından yapılan işlemleri kalıcı hale getirmektir. Java'nın java.io paketi, hesaplama sonuçlarını bir metin dosyasına yazmanıza olanak tanır. Bu sayede kullanıcı, programı kapatsa bile geçmiş işlemlerine erişebilir.
Aşağıdaki kod örneği, yapılan her işlemi gecmis.txt dosyasına nasıl ekleyebileceğinizi göstermektedir:
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Logger {
public static void logIslem(String islem) {
try (FileWriter fw = new FileWriter("gecmis.txt", true);
PrintWriter pw = new PrintWriter(fw)) {
pw.println(islem);
} catch (IOException e) {
System.err.println("Dosyaya yazma hatası: " + e.getMessage());
}
}
}
Bu metodu, hesap makinenizdeki her işlem sonucundan hemen sonra çağırarak, uygulamanıza bir "işlem günlüğü" özelliği kazandırabilirsiniz.
Hesap Makinesi Uygulamasında Birim Testleri (Unit Testing)
Yazılım geliştirmede kodun doğruluğunu manuel olarak test etmek yerine, JUnit gibi kütüphanelerle otomatik testler yazmak endüstri standardıdır. Hesap makinenizin toplama, çıkarma veya bölme fonksiyonlarının her zaman doğru sonuç verdiğinden emin olmak için bir test sınıfı oluşturabilirsiniz.
Örnek bir test senaryosu şu şekildedir:
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class HesapMakinesiTest {
@Test
public void testToplama() {
double sonuc = HesapMakinesi.topla(5, 10);
assertEquals(15.0, sonuc, "Toplama işlemi hatalı!");
}
@Test
public void testBolmeSifirHatasi() {
// Sıfıra bölme durumunda beklentiniz (örneğin 0 dönmesi veya hata fırlatması)
double sonuc = HesapMakinesi.bol(10, 0);
assertEquals(0, sonuc, "Sıfıra bölme durumu yönetilmedi!");
}
}
Bu yaklaşım, kodunuzda ileride yapacağınız değişikliklerin mevcut fonksiyonları bozup bozmadığını saniyeler içinde kontrol etmenizi sağlar. Profesyonel yazılım geliştirme süreçlerinde, kodun "çalıştığından" emin olmak için test odaklı geliştirme (TDD) metodolojisi sıkça tercih edilir.
Sonuç
Java ile konsol üzerinden hesap makinesi yapmak, dilin temel yapı taşlarını öğrenmek için harika bir adımdır. Bu rehberde; Scanner kullanımı, kontrol akış yapıları, hata yönetimi ve metotların modüler kullanımını ele aldık. Artık basit bir hesap makinesinden, kullanıcı girdilerini doğrulayan ve döngüsel çalışan bir uygulamaya sahipsiniz.
Bir sonraki adım olarak, bu projeye "geçmişi kaydetme" özelliği ekleyerek, yapılan işlemlerin bir dosyaya yazılmasını (File I/O) öğrenebilirsiniz. Yazılım yolculuğunuzda başarılar dilerim.


Yorumlar (0)
Yorum Yaz