Belirgin Arayüzler
Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 28 / 70.
Bir sınıf, aynı ada sahip üyelere sahip birden çok arabirim uyguladığında ad çakışmasıyla karşılaşırsınız. Açık arabirim uygulaması, her arabirim için ayrı uygulamalar sağlamanıza olanak tanıyarak bu sorunu çözer.
Açık uygulama (explicit implementation) ile, üye adının önüne arayüz adını getirirsiniz ve erişim belirleyicisini atlarsınız:
public interface IAmericanPlug
{
void Connect();
}
public interface IEuropeanPlug
{
void Connect();
}
public class UniversalAdapter : IAmericanPlug, IEuropeanPlug
{
void IAmericanPlug.Connect()
{
Console.WriteLine("Connected to 120V");
}
void IEuropeanPlug.Connect()
{
Console.WriteLine("Connected to 220V");
}
}Açıkça uygulanan üyelere yalnızca arayüz türündeki bir değişken aracılığıyla erişilebilir, sınıfın kendisi üzerinden erişilemez:
var adapter = new UniversalAdapter();
// adapter.Connect(); // Derlenmeyecek!
IAmericanPlug american = adapter;
american.Connect(); // 120V'a bağlandı
IEuropeanPlug european = adapter;
european.Connect(); // 220V'a bağlandıBu teknik, arayüz üyelerini sınıfın genel API'sinden gizlemek istediğinizde de yararlıdır. Bir yöntem yalnızca nesneye belirli bir arayüz olarak yaklaşıldığında anlamlıysa, açık uygulama (explicit implementation) sözleşmeyi yerine getirirken sınıfınızın yüzey alanını temiz tutar.
Görev
KolayTek bir sınıfın, kullanılan arayüze bağlı olarak farklı davranışlar sunmasını sağlayan açık arayüz uygulamasının nasıl çalıştığını gösteren bir rapor oluşturma sistemi geliştirelim. Görüntüleme ve yazdırma için farklı biçimlendirilebilen bir belge oluşturacaksın.
Kodunu dört dosya arasında düzenleyeceksin:
IDisplayable.cs:IDisplayablead alanındaReportsadlı bir arayüz tanımla. Bu arayüz, ekranda gösterilebilen içeriği temsil eder. Bir dize döndürenRender()metodunu bildirmelidir.IPrintable.cs:IPrintablead alanındaReportsadlı bir arayüz tanımla. Bu arayüz, yazıcıya gönderilebilen içeriği temsil eder. O da bir dize döndürenRender()metodunu bildirmelidir - bununIDisplayableile bir ad çakışması oluşturduğuna dikkat et!Report.cs:Reportad alanında hemReportshem deIDisplayableuygulayan birIPrintablesınıfı tanımla. Raporun birTitleözelliği (string) ve birContentözelliği (string) olmalı; ayrıca her iki değeri de ayarlayan bir kurucu içermelidir. FarklıRender()davranışları sağlamak için açık arayüz uygulamasını kullan:- Ekranda görüntülendiğinde:
"[SCREEN] {Title}: {Content}" - Yazdırıldığında:
"[PRINT] {Title} | {Content}"
- Ekranda görüntülendiğinde:
Program.cs: Ana dosyanda, giriş değerlerini kullanarak birReportoluştur. Açık uygulamalara yalnızca arayüz değişkenleri üzerinden erişilebildiğinden aynı raporu hem birIDisplayabledeğişkeninde hem de birIPrintabledeğişkeninde sakla; ardından hangi arayüzü kullandığına bağlı olarak aynı nesnenin nasıl farklı çıktı ürettiğini göstermek için her birindeRender()metodunu çağır.
İki giriş alacaksın:
- Rapor başlığı
- Rapor içeriği
Çıktıyı şu biçimde yazdır:
Display version:
{Render() via IDisplayable}
Print version:
{Render() via IPrintable}Örneğin girişler Sales Report ve Q4 revenue increased by 15% ise çıktı şu şekilde olmalıdır:
Display version:
[SCREEN] Sales Report: Q4 revenue increased by 15%
Print version:
[PRINT] Sales Report | Q4 revenue increased by 15%Aynı Report nesnesinin, ona erişmek için kullandığın arayüz başvurusuna bağlı olarak nasıl farklı davrandığına dikkat et. Açık arayüz uygulamasının gücü budur - ad çakışmalarını çözerken bağlama uygun davranış sağlamak!
Kendin dene
using System;
using Reports;
class Program
{
public static void Main(string[] args)
{
// Girdiyi oku
string title = Console.ReadLine();
string content = Console.ReadLine();
// TODO: title ve content ile bir Report nesnesi oluşturun
// TODO: Raporu bir IDisplayable değişkeninde saklayın
// TODO: Aynı raporu bir IPrintable değişkeninde saklayın
// TODO: IDisplayable üzerinde Render() metodunu çağırarak ekran sürümünü yazdırın
Console.WriteLine("Display version:");
// Render sonucunu buraya yazdırın
// TODO: IPrintable üzerinde Render() metodunu çağırarak yazdırma sürümünü yazdırın
Console.WriteLine("Print version:");
// Render sonucunu buraya yazdırın
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci KayıtlarıKendi başına pratik yap: Online C# derleyicisi