0% found this document useful (0 votes)
13 views11 pages

Ders11 Inheritance

Uploaded by

aydinbjk650
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views11 pages

Ders11 Inheritance

Uploaded by

aydinbjk650
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Nesneye Yönelik Programlama - C# Ders Notları

Dr. Suat KARAKAYA

Inheritance (Kalıtım/Miras)
NYP uyumlu geliştirme ortamlarında polymorphism (çok biçimlilik) sağlamanın bir yolu da kalıtım
yoluyla sınıf türetmektir. Temel olarak kalıtım işlemi, bir sınıftan başka bir sınıf türetme işlemidir. Bu
yaklaşımla var olan sınıflar geliştirilebilir veya yeni bir sınıf tanımlanabilir.

Uygulamalarımızda yazacağımız sınıfa benzer özelliklere sahip bir sınıf elimizde zaten varsa, bu sınıfı
yazacağımız yeni sınıfa aktararak ihtiyaç duyduğumuz bazı özelliklerini kullanabiliriz. Yapılan işlem
asıl sınıfı miras alarak ondan yeni bir sınıf türetmektir.

Yeni oluşan sınıf türemiş sınıf (derived class), miras veren sınıf ise temel sınıf (base class) olarak
isimlendirilir. Türemiş sınıf temel sınıfın izin verilen tüm özelliklerini taşır. Ayrıca yeni üyeler
eklenerek genişletilebilir. Türemiş sınıf da bir başka sınıfa miras yoluyla aktarılabilir.

Bir sınıf birden fazla sınıfa kalıtım yoluyla aktarılabilir. Ancak sadece bir sınıftan kalıtım alabilir.
Kalıtım işlemi “:” operatörü ile gerçekleştirilir.

Bir Base class (Temel sınıf)’tan bir derived class (türeyen sınıf)’a miras yoluyla
sınıf üyelerini nasıl aktarırız? Örnek bir uygulama ile görelim:
class TemelSinif
{
TemelSinif classında 3 üye
internal int x;
tanımlanmıştır: x(field),
internal int y { get; set; }
y(property), metot1(metot).
internal void metot1()
{
[Link]("TemelSinif metodu...");
}
}
class TureyenSinif : TemelSinif TureyenSinif classında herhangi bir
{ üye bulunmuyor. Tüm üyeleri
} kalıtımdan geliyor.
class Program
{
static void Main(string[] args)
{
TureyenSinif t1 = new TureyenSinif();
t1.x = 2;
t1.y = 8; “x” alanı, “y” özelliği ve “metot1”
t1.metot1(); metodu TemelSinif classından miras
[Link](); alınmıştır.
}
}
▪ Inheritance (kalıtım/miras) yolulya birden fazla sınıftan üye kazanılamaz. Bu
girişim derleme hatası ile sonuçlanacaktır.
class Person1
{
public string Name { get; set; }
public string Surname { get; set; }
}
class Person2
{
public string Departmet { get; set; }
public string City { get; set; } Student classı Person1 ve Person2
} classlarından kalıtım almak istediğinde bu
class Student : Person1, Person2 geçersiz bir işlem olarak kabul
{ edilecektir. (Person1 ve Person2 interface
public int StudentId { get; set; } olsaydı bu mümkün olabilirdi.)
}
Nesneye Yönelik Programlama - C#
Bir Base classtan (Person) birden çok derived classa (Student ve Worker) miras
yoluyla sınıf üyelerini nasıl aktarırız? Örnek bir uygulama ile görelim:
class Person
{
Person classında 2 adet property bulunuyor:
public string Name { get; set; }
“Name”, “Surname”.
public string Surname { get; set; }
Bu property’ler miras olarak Student ve
}
Worker classlarına aktarılmak isteniyor.
class Student : Person
{
public int StudentId { get; set; } Student classında kendisinde ait 1 üye var.
} Bu üye miras değil: “StudentId”.
class Worker : Person
{
public int WorkerId { get; set; } Worker classında kendisinde ait 1 üye var.
} Bu üye miras değil: “WorkerId”.
class Program
{
static void Main(string[] args) Worker classı: kendisinde ait 1 üye + miras
{ aldığı 2 üyeye sahiptir.
Student std1 = new Student(); Student classı: kendisinde ait 1 üye + miras
Worker wrk1 = new Worker(); aldığı 2 üyeye sahiptir.
Person prs1 = new Person(); Person classı: kendisinde ait 2 üyeye
} sahiptir.
}

▪ Interface kullanarak yaptığımız işlemler (implementasyonlar), class inheritance ile yaptığımız


işlemlere benzemektedir. Aradaki temel fark, interface’ler tek başına bir anlam ifade etmezken, kalıtım
veren (base class) tek başına kullanılabilen bağımsız bir sınıftır. Bir diğer fark ise interface kullanırken
çoklu implementasyon (çoklu kalıtım) yapılabilirken, sınıf kalıtımında tek bir base classtan kalıtım
alınabilir. Uygulamada sadece derived classlar kullanılacaksa bir başka deyişle base sınıf yapısına
ihtiyaç yoksa interface kullanımı daha mantıklı bir çözüm olacaktır. Ancak kısıtlanmış bir base class
veya abstract class (ilerleyen notlarda bahsedilecek) gerekliliği varsa sınıf kalıtımı uygulamak daha
doğru bir çözüm olacaktır.

Access Modifiers (Erişim Bildirgeçleri)

▪ Private: Sadece tanımlı olan blokta (sınıf vb.) geçerlidir.


▪ Protected: Sadece tanımlı olduğu blokta geçerlidir. Ekstra olarak inherit edildiği sınıflarda da
tanımlıdır. Private ile yapılamayan bu işlem protected seviyesinde yapılabilir.
▪ Internal: Bağlı bulunduğu proje (Assembly) içerisinde referans ihtiyacı duyulmadan
kullanılabilir. Aynı Namespace altındaki alanlara erişebilir. Assembly dışında erişilemez.
Class’lar varsayılan olarak internal seviyesindedir.
▪ Public: Harici bir projeden de erişilebilen alanlardır. Referans eklendikten sonra ve using
<Namespace> satırının eklenmesinin ardından tüm projelerde public tanımlanmış elemanlara
erişilebilir.

Virtual Methods (Sanal Metotlar)

Base class içerisinde varsayılan bir içerik ile tanımlanmış bir metot virtual sözcüğü ile tanımlanırsa,
miras alan bir sınıf (derived class) içerisinde içeriği yeniden yazılabilir. (Metot varsayılan formatından
çıkarılarak üzerine yazılabilir). Bu işleme override adı verilir. Derived class içerisinde, yeniden
yapılandırılmak istenen bir virtual metot, override ön sözcüğü ile tanımlanır. Bu işlem sonucunda,
virtual metodun yapısı sadece override yapan türeyen sınıfta değişir. Temel sınıfta ve varsa diğer
türeyen sınıflarda değişim olmaz.

2
Nesneye Yönelik Programlama - C#
Virtual metotları ve override işlemini bir problem üzerinde inceleyelim:
▪ Communicate isimli sınıf içerisinde varsayılan bir veri gönderme metodu yazılıyor.
▪ Bu metodun birçok haberleşme terminali (hyper, siow, vb.) için ortak bir çözüm
sunduğu varsayılıyor ve varsayılan metotları içeren Communicate sınıfı tüm haberleşme
terminallerine base olarak kalıtım veriyor.
▪ Ancak bazı terminallerde (örn. docklight) data göndermek için varsayılan yöntemin
dışında ekstra birtakım işlemler yapılması veya tamamen farklı bir operasyon
gerçekleştirilmesi gerekiyor.
▪ Az sayıda olsa da bu istisnaları yönetebilmek için base classta tanımlı Send()
metodunda değişiklik yapılmasına yetki verilmesi istenmektedir.
▪ Bu yetkiyi vermek için Send() metodu “virtual” olarak tanımlanmıştır.
▪ Virtual olarak tanımlandıktan sonra miras alan sınıfların tümü varsayılan Send()
metodunu kullanmaya devam edebilir. Ekstra bir işleme gerek yoktur. Ancak virtual
sözcüğü bu metodun türeyen sınıflar tarafından yeniden tasarlanmasına izin
vermektedir. Bu yetki kullanılarak Docklight sınıfı içerisinde Send() metodu istenilen
biçimde yeniden tasarlanmıştır.
class Communicate
{
public virtual void Send()
{
[Link]("data sended (default)");
}
public void Receive()
{
[Link]("data received (default)");
}
}
class Docklight : Communicate
{
public override void Send()
{
[Link]("data send via Docklight");
}
}
class Hyper : Communicate
{
}
class Program
{
static void Main(string[] args)
{
Hyper hyp1 = new Hyper();
Docklight dc1 = new Docklight();
[Link]();
[Link]();
[Link]();
[Link]();
}
}
[Link]();
[Link]();
[Link]();

Açıklamalar:
Hyper sınıfı, kalıtım aldığı Communicate sınıfının Send() metodunu olduğu gibi kullanmayı
tercih etmiştir. Bunu yapmak için (Send metodu virtual olarak tanımlanmış olsa dahi)
inheritance operasyonu dışında bir işlem yapılmasına gerek yoktur.
Ancak,
Docklight sınıfı, kalıtım aldığı Communicate sınıfının Send() metodunu kullanmak yerine
kendine özgü bir Send metodu uygulamayı tercih etmektedir. Bunu yapmak için metodun

3
Nesneye Yönelik Programlama - C#

adını değiştirmeksizin override sözcüğünü kullanarak metodun içeriğini tekrar yazma şansına
sahiptir.
Docklight sınıfı Receive() metodunu da kalıtım yolu ile Communicate sınıfından almıştır.
Ancak bu metodu olduğu gibi kullanmaktadır. Override yapmamıştır. Zaten Receive metodu
temel sınıfta virtual olarak tanımlanmadığı için istense bile override işlemine tabi tutulamaz.
Özetle , inheriance yaptığımız sınıfta (temel sınıf/base class) genel bir operasyon var ve her
ortamda bu operasyon aynı şekilde yapılıyorsa, bu operasyonu virtual tanımlamaya gerek
yoktur. Ama bazı ortamlarda değişik bir formatta kullanmak gerekiyorsa bu operasyonu
yeniden yazmamız gerekiyorsa, temel sınıftan bunun için izin alınması gerekir. Bunu sağlayan
ön sözcük ise virtual sözcüğüdür.

base sözcüğü: türeyen sınıf içerisinde temel sınıfın üyelerine erişmek için kullanılan ifadedir.
Base class’ı temsil eden sözcüktür. Temel sınıfta tanımlı bir operasyonu kullanmadan önce
özel bir konfigürasyon yapılması gerekiyorsa, türeyen sınıf içerisinde override yapılarak önce
bu konfigürasyon gerçekleştirilir, sonra “[Link]()” gibi bir işlem adımı ile temel sınıf
metodu çağırılabilir.

class Communicate
{
public virtual void Send()
{
[Link]("data sended (default)");
}
public void Receive()
{
[Link]("data received (default)");
}
}
class Docklight : Communicate
{
public override void Send()
{
[Link]("gerekli ön konfigurasyonlar yapıldı.");
[Link]();
}
}

Açıklamalar:
Docklight sınıfı, kalıtım aldığı Communicate sınıfının Send() metodunu olduğu gibi
kullanabilmektedir. Ancak bu metodu kullanmadan önce kendine has bir takım ön işlemler
gerekli olduğu ve bu konfigürasyonlar yapıldıktan sonra base classtaki Send() metodunun
kullanılabileceği varsayılsın. Bu durumda 2 seçeneğimiz var:
1. Docklight sınıfında override Send() metodu altında tüm konfigürasyonlar ve veri gönderme
protokolleri dahil sıfırdan yeni bir metot yazmak,
2. Docklight sınıfında override Send() metodu altında sadece bu sınıfa ait ön konfigürasyonları yazıp,
veri gönderme protokolleri ile ilgili işlemleri temel sınıftan olduğu gibi almak.

4
Nesneye Yönelik Programlama - C#

Verilen örnekte 2. Yol tercih edilmiştir. 1. seçenek de aynı sonucu verecektir ancak Send() metodunun
içerdiği varsayılan veri gönderme protokolleri temel sınıfta verilen varsayılan metot ile kalıtım alan
Docklight sınıfında ortak olduğu için bunu tekrar sıfırdan yazmak verimli olmayacaktır. Bu tip
durumlarda base sözcüğü aracılığı ile temel sınıf referans gösterilebilir ve varsayılan metotlar override
metotlar altında çağırılabilir.
▪ Interface’ler ile class inheritance arasında tercih yaparken gözetilebilecek bir kriter de bu konu
olarak düşünülebilir. Örnekte verilen tipte bir durum varsa class inheritance yaklaşımı daha doğru bir
çözüm olacaktır.

Veri Saklama (Data Hiding/Shadowing)

Inheritance işlemi sırasında temel sınıf altında tanımlı bir metot yeniden tasarlanmak istenebilir.
Temel sınıfta tanımlanmış (kalıtım alınan) metodu değiştirmeden türeyen sınıf altında ilgili metot veri
saklama (veri gizleme-shadowing vb.) tekniği ile yeniden yüklenebilir. Veri gizleme işlemi temel
olarak türeyen sınıfta ilgili metodun prototip satırına new sözcüğü eklenerek gerçekleştirilir.

class Personel
{
public string Name { get; set; }
public string Kurum { get; set; }
public void GorevYap()
{
[Link]("görev gerçekleştirildi");
}
}
class Doktor : Personel
{
public string Uzmanlik { get; set; }
public new void GorevYap() // data shadowing
{
[Link]("Hastahanedeki gorev gerçekleştirildi");
}
}
static void Main(string[] args)
{
Doktor dr1 = new Doktor();
[Link]();
[Link]();
}

Bu aşamada şu soru aklımıza gelebilir: Veri saklama yaklaşımı ile temel sınıfın bir metodu
override işleminde yapılan operasyona benzer şekilde güncellenebiliyorsa virtual metotları
neden kullanırız? Kısaca, virtual metot overriding ile data shadowing operasyonlarının en
temel farkı nedir?

Bu sorunun cevabı temel ve türeyen sınıflardan nesne türetirken temel sınıf referansını
kullandığımızda ortaya çıkmaktadır. Virtual metotların ekstra bir özelliği olan dinamik çok
biçimlilik (dynamic polymorphism), program yazarken temel sınıf referansı ile tanımlanan bir
nesnenin dinamik olarak programın akışında istenilen herhangi bir üye sınıfa (türeyen
sınıfların herbirine) referans gösterilebilmesidir.

5
Nesneye Yönelik Programlama - C#
Örneğin: aşağıda verilen uygulamada Personel sınıfında tanımlı dr1 ve dr2 nesneleri temel ve
türeyen sınıfa referans gösterilmiştir. Bu durumda temel sınıf referanslı olan nesne
GorevYap() metodunu temel sınıf için çağırmış, türeyen sınıf referanslı nesne ise türeyen sınıf
için çağırmıştır.
Class Personel
{
public string Name { get; set; }
public string Kurum { get; set; }
public virtual void GorevYap()
{
[Link]("görev gerçekleştirildi");
}
}
class Doktor : Personel
{
public string Uzmanlik { get; set; }
public override void GorevYap()
{
[Link]("Hastanedeki gorev gerçekleştirildi");
}
}
static void Main(string[] args)
{
Personel dr1 = new Doktor();
[Link]();
Personel dr2 = new Personel();
[Link]();
[Link]();
}

Aynı operasyonu data shadowing ile gerçekleştirelim: bu durumda temel sınıf referansı ile
tanımlanan nesneler her durumda referans olarak tanımlanan sınıfın metodunu çağıracaktır.
Dinamik çok biçimlilik (dynamic poymorphism) ilkesi bu aşamada geçersizdir.
class Personel
{
public string Name { get; set; }
public string Kurum { get; set; }
public void GorevYap()
{
[Link]("görev gerçekleştirildi");
}
}
class Doktor : Personel
{
public string Uzmanlik { get; set; }
public new void GorevYap()
{
[Link]("Hastanedeki gorev gerçekleştirildi");
}
}
static void Main(string[] args)
{
Personel dr1 = new Doktor();
[Link]();
Personel dr2 = new Personel();
[Link]();
[Link]();
}

6
Nesneye Yönelik Programlama - C#

Constructor Inheritance (Yapıcı Metot Kalıtımı)


Yapıcı metotlar da sınıf kalıtımı işleminden etkilenir. Temel sınıfın yapıcıları, türeyen sınıftan nesne
türetildiğinde tetiklenir. “new” operasyonu sonucunda türeyen sınıfın kendi içinde tanımlanan
yapıcılar da doğal olarak devreye girer. Hatırlarsak yapıcı metotlar parametresiz (default constructor),
parametreli (parameterized constructor) ve statik (static constructor) biçiminde tasarlanabiliyordu.
Temel ve türeyen sınıflara ait çeşitli türden yapıcıların hangi sıra ile ve nasıl inheritance işleminden
etkilendiğini inceleyelim:

a. Türeyen sınıfta ve temel sınıfta varsayılan yapıcı (default constructor) çağırılması sırasında
öncelikle temel sınıfın yapıcısı tetiklenir. Daha sonra türeyen sınıfın varsayılan yapıcı metodu
koşturulur.

class MyClass1
{
public MyClass1()
{
[Link]("This is default constructor of MyClass1 (base class)");
}
}
class MyClass2 : MyClass1
{
public MyClass2()
{
[Link]("This is default constructor of MyClass2 (derived class)");
}
}
static void Main(string[] args)
{
MyClass2 testCass = new MyClass2();
[Link]();
}
}

b. Türeyen sınıfta ve temel sınıfta parametreli (parameterized) ve varsayılan (default) yapıcılar


birlikte bulunuyorsa yapıcıların çağırılması öncelikle temel sınıftan başlar. Ancak temel
sınıfın parametreli yapıcısı türeyen sınıfın parametresini doğrudan tanıyamaz. Bu
yüzden aksi belirtilmemişse temel sınıfın parametreli değil varsayılan yapıcı metodu çağırılır.
Daha sonra türeyen sınıfın parametreli yapıcı metodu koşturulur.

class MyClass1
{
public MyClass1()
{
[Link]("This is default constructor of MyClass1 (base class)");
}
public MyClass1(int p)
{
[Link]("This is parameterized constructor of MyClass1 (base class)");
}
}
class MyClass2 : MyClass1
{
public MyClass2()

7
Nesneye Yönelik Programlama - C#
{
[Link]("This is default constructor of MyClass2 (derived class)");
}
public MyClass2(int p)
{
[Link]("This is parameterized constructor of MyClass2(derived class)");
}
}
static void Main(string[] args)
{
MyClass2 testCass = new MyClass2(5);
[Link]();
}

c. Türeyen sınıfta ve temel sınıfta parametreli (parameterized constructor) yapıcı çağırılması


işleminde öncelik yine temel sınıftadır. Bu işlem için özel olarak base sözcüğü temel sınıfın
parametreli yapıcısına parametre göndermek için kullanılır. Türeyen sınıf içerisindeki
parametreli yapıcının prototip satırına base(<parametre>) formatında bir komut eklenerek
aynı parametrenin temel sınıfa da gönderilmesi sağlanır. Yapıcı metotlar sırayla çağırılırken
önce temel sınıfın parametreli yapıcısı, sonra türeyen sınıfın parametreli yapıcısı koşturulur.

class MyClass1
{
public MyClass1()
{
[Link]("This is default constructor of MyClass1 (base class)");
}
public MyClass1(int p)
{
[Link]("This is parameterized constructor of MyClass1 (base class)");
}
}
class MyClass2 : MyClass1
{
public MyClass2()
{
[Link]("This is default constructor of MyClass2 (derived class)");
}
public MyClass2(int p) : base(p)
{
[Link]("This is parameterized constructor of MyClass2(derived class)");
}
}
static void Main(string[] args)
{
MyClass2 testCass = new MyClass2(5);
[Link]();
}

8
Nesneye Yönelik Programlama - C#
d. Statik yapıcıların çalıştırılma sırası ise statik olmayan (varsayılan, parametreli) yapıcılardan
farklıdır. Sıralamada önce türeyen sınıfın statik yapıcı metodu, ardından temel sınıfın statik
yapıcısı tetiklenir. Ek olarak sınıflarda statik olmayan yapıcılar da varsa öncelikle temel sınıfın
yapıcıları, sonra türeyen sınıfın yapıcıları koşturulur.

class MyClass1
{
public MyClass1()
{
[Link]("This is default constructor of MyClass1 (base class)");
}
public MyClass1(int p)
{
[Link]("This is parameterized constructor of MyClass1 (base class)");
}
static MyClass1()
{
[Link]("This is static constructor of MyClass1 (base class)");
}
}
class MyClass2 : MyClass1
{
public MyClass2()
{
[Link]("This is default constructor of MyClass2 (derived class)");
}
public MyClass2(int p) : base(p)
{
[Link]("This is parameterized constructor of MyClass2 (derived class)");
}
static MyClass2()
{
[Link]("This is static constructor of MyClass2 (derived class)");
}
}
static void Main(string[] args)
{
MyClass2 testCass = new MyClass2(5);
[Link]();
}

Abstract Class (Soyut Sınıf)


Soyut sınıflar da interface kullanımına ve virtual metotlara benzer bir amaçla tanımlanır. Hatırlarsak,
interface’ler içerisinde belli prototipleri tanımlayıp, implemente edilen sınıflar içinde bu prototipleri
tam olarak tanımlamayı zorunlu hale getirmiştik. Virtual metotlarda ise belirlediğimiz operasyonları
kalıtım yoluyla alan türeyen sınıflar, override işlemi ile bu metotları yeniden tanımlayabiliyordu.
Ancak interface’lerdeki gibi bir zorunluluk yoktu. Abstract classlar ise interface ile virtual metotların
bir kesişimi gibi düşünülebilir. Interface gibi soyut kavramlar değildir, gerçek metotlar içerebilir.
Ancak interface’ler gibi, kalıtım verdiği sınıfta üyelerin override edilmesini zorunlu kılar. İsteğe bağlı
olarak ister tüm üyeler, ister seçilen üyeler override edilmeye mecbur bırakılabilir. Soyut sınıflar
sadece ve sadece inheritance vermek için tanımlanırlar. Interface’ler ile benzer biçimde new
operasyonu ile türetilemezler.

9
Nesneye Yönelik Programlama - C#

Abstract classlar hem tamamlanmış hem de prototip üyeler içerebilir. (interfaceler sadece
prototip içerebilir.)
Tamamlanmış olarak verilen üyeler miras alan sınıflarda doğrudan kullanılabilir.
Prototip olarak verilen üyeler “abstract” sözcüğü ile tanımlanır ve miras alan sınıflarda
override edilmesi zorunludur.
Abstract bir sınıf üyesi, türeyen bir sınıfta tamamlanmış olarak override edilmezse derleyici
hatası oluşacaktır.
✓ Hatırlatma1: Virtual metotlarda böyle bir durum yoktu. Virtual metotlar istenirse override
edilebilir, zorunlu değildir.
✓ Hatırlatma2: interface’lerde böyle bir durum vardı. Prototip olarak bulunan bir üye
implemente edilen sınıfta – inheritance olarak da adlandırılabilir – tamamlanmış olarak
tanımlanmak zorundadır.
Abstract class konusunu bir örnek problem üzerinden açıklayalım: Haberleşme işlemi
gerçekleştiren 2 terminal programı kullanan bir yazılım için bir veri yönetimi programı yazmak
istiyoruz. Terminaller : hyper, siow.
Haberleşme yönetimi için kullanılan temel bir sınıf tanımlayalım. Bu sınıf içerisinde veri
gönderme ve veri okuma operasyonlarını gerçekleştiren 2 adet metot bulunsun. (Send() ve
Read())
Veri gönderme işlemi, tüm haberleşme terminalleri için ortak bir şekilde gerçekleştiği
varsayılsın.
Veri okuma operasyonu ise, istisnasız tüm terminaller için benzersiz birer teknikle
gerçekleştirildiği varsayılsın.
Bu durumda tüm terminaller ortak veri gönderme metodunu kullanacak, ancak veri okuma
aşamasında her terminal kendi özgün veri okuma metodunu kullanacaktır.
abstract class Communication
{
public void Send()
{
[Link]("Data gönderildi (default). ");
}
public abstract void Read();
}
class Hyper : Communication
{
public override void Read()
{
[Link]("Hyper terminal'e özel data okuma işlemi...");
}
}
class Siow : Communication
{
public override void Read()
{
[Link]("Siow terminal'e özel veri okuma işlemi...");
}
}

Verilen sınıf tanımlamaları dahilinde main() metodu altında bu sınıflardan nesneler türeterek hangi
metotları koşturabildiklerini inceleyelim:

class Program
{
static void Main(string[] args)
{

10
Nesneye Yönelik Programlama - C#
Siow siow1 = new Siow();
Hyper hyper1 = new Hyper();
[Link]();
[Link]();
[Link]();
[Link]();
[Link]();
}
}
Communication soyut sınıfında tanımlı.
Siow sınıfında override edildi.
Communication soyut sınıfında tanımlı.
Hyper sınıfında override edildi.

11

You might also like