330 likes | 565 Views
Nesneye Dayal ı Programlama. DERS 5. INHERITANCE (TÜRETME/KALITIM). Türetme ( inheritance ) nesne yönelimli programlama tekniğinin en önemli araçlarındandır.
E N D
Nesneye Dayalı Programlama DERS 5 Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
INHERITANCE(TÜRETME/KALITIM) • Türetme (inheritance) nesne yönelimli programlama tekniğinin en önemli araçlarındandır. • Türetme yoluyla önceden tanımlanmış olan bir sınıfın üzerinde değişiklik yapmadan,sınıfın işlevleri genişletilebilir. Önceden tanımlanmış olan sınıflar kalıtım işlemi ile gereksinimlere göre biçimlendirebilir. • Türetme yoluyla bir sınıf başka bir sınıfın var olan özelliklerini alarak, o sınıf türünden bir nesneymiş gibi kullanılabilir. Türetme, nesne yönelimli programlamanın olmazsa olmaz araçlarındandır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Daha önce yazılmış olan bir sınıfa ekleme yapılması istendiğinde başvurulacak en iyi yöntem türetme işlemidir. • Bir sınıfa ek yapmak sınıfa yeni veri ve üye fonksiyonu eklemek anlamındadır. • Bir sınıfa ek yapmak için türetme dışında birkaç yöntem akla gelebilir: Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Bir sınıfın işlevleri türetme yoluyla genişletilecekse türetmenin yapılavcağı sınıfa taban sınıf (base class), türetilmiş olan sınıfa da türemiş sınıf (derived class) denir. Şekilsel olarak türemiş sınıftan taban sınıfa bir ok olarak belirtilir. • Türetme işleminin genel biçimi: Türetme biçimi class <türemiş sınıf ismi>:[private/protected/public]<taban sınıf ismi> { } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Örnek: class A { public: int a; //... }; class B:public A { int b; //... }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
İki nokta üstüste ayıracından sonra isteğe bağlı olarak türetme biçimi yazılabilir. Yazılmazsa private yazılmış gibi işlem görür. • Türemiş sınıf türünden bir nesne tanımlandığında bu nesne hem taban sınıf veri elemanlarını hem de türemiş sınıf veri elemanlarını içerir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Türemiş Sınıf Nesnesinin Bellekteki Organizasyonu Örnek: /*-----turetme.cpp-----*/ #include <stdio.h> class A { public: int a; }; class B:public A { public: int b; }; void main(void) { B x; printf("%d\n", sizeof(x)); } /*------------------------*/ Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Türemiş Sınıf Nesnesinin Bellekteki Organizasyonu • Türemiş sınıf nesnesinin taban sınıf veri elemanları ve türemiş sınıfın kendi veri elemanları blok olarak ardışıl bir biçimde yerleştirilir. Ancak taban sınıf ve türemiş sınıf veri elemanlarının hangisinin daha düşük adres bölgesine yerleştirileceği ANSI standartlarında belirlenmemiştir, dolayısıyla derleyiciyi yazanlara bırakılmıştır. • Derleyici organizasyonu hep aynı yapar. Yaygın kullanılan derleyicilerde taban sınıf veri elemanları düşük anlamlı adresi yerleştirilmektedir Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Türemiş Sınıflarda Erişim Kuralı • Türemiş sınıflardaki erişim kuralı türetme biçimine bağlıdır. Public Türetmesi • Public türetmesinde taban sınıfın public bölümü türemiş sınıfın public bölümüymüş gibi, taban sınıfın protected bölümü de türemiş sınıfın protected bölümüymüş gibi işlem görür. Taban sınıfın private bölümü erişime kapalıdır. Taban sınıfın private bölümüne türemiş sınıf tarafından erişilemez. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Public Türetmesinden Çıkan Sonuçlar • Türemiş sınıf nesnesi yoluyla dışarıdan nokta ya da ok operatörü kullanılarak taban sınıfın public bölümüne erişilebilir. Ancak taban sınıfın protected ve private bölümüne erişilemez. • Türemiş sınıf üye fonkiyonları içerisinde taban sınıfın public ve protected bölümlerine doğrudan erişilebilir.ancak taban sınıfın private bölümüne erişilemez. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Protected Türetmesi • Bu türetme biçiminde taban sınıfın public ve protected bölümleri türemiş sınıfın protected bölümüymüş gibi işlem görür. Taban sınıfın private bölümü erişime kapalıdır. Türemiş sınıf tarafından erişilemez. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Protected Türetmesinden Çıkan Sonuçlar • Türemiş sınıf nesnesiyle dışarıdan nokta ya da ok operatörüyle taban sınıfın hiçbir bölümüne erişilemez. • Türemiş sınıf üye fonksiyonları içerisinde taban sınıfın public ve protected bölümlerine doğrudan erişilebilir. Ancak private bölümlerine erişilemez. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Private Türetmesi • Bu durumda taban sınıfın public ve protected bölümleri türemiş sınıfın private bölümüymüş gibi işlem görür. Taban sınıfın private bölümü erişime kapalıdır. Türemiş sınıf tarafından erişilemez. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Private Türetmesinden Çıkan Sonuçlar • Türemiş sınıf nesnesi yoluyla dışarıdan nokta ya da ok operatörüyle taban sınıfın hiçbir bölümüne erişilemez. • Türemiş sınıf üye fonksiyonları içerisinde taban sınıfın public ve protected bölümlerine doğrudan erişilebilir. Ancak private bölümlerine erişilemez. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Türetme İşleminden Çıkan Ortak Sonuçlar • Türemiş sınıf nesnesi yoluyla dışarıdan nokta veya ok operatörü kullanılarak ancak taban sınıfın public bölümüne ancak public türetmesiyle erişilebilir. Hiçbir zaman dışarıdan taban sınıfın protected ya da private bölümüne erişilemez. • Türemiş sınıf üye fonksiyonları içerisinde türetme biçimi ne olursa olsun taban sınıfın public ve protected bölümlerine erişilebilir. • Taban sınıfın private bölümü tam olarak korunmuştur. Türemiş sınıf tarafından doğrudan hiçbir şekilde erişilemez. • En çok kullanılan türetme biçimi public türetmesidir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Protected Bölümünün Anlamı • Protected bölüm dışarıdan doğrudan erişilemeyen, ancak türemiş sınıf üye fonksiyonları tarafından erişilebilen bir bölümdür. Protected bölümünün türetme dışında özel bir anlamı yoktur. Çünkü bu bölüm türemiş sınıfın çeşitli işlemlerini kolaylaştırmak için gereksinimlerini tutmakta kullanılır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Private Bölüme Fonksiyonları Yerleştirilmesi • Bir sınıfın public bölümünde bulunan X() isimli fonksiyon işlemini gerçekleştirmek için işlemin belirli bölümlerini yapan, yani ara işlemleri yapan çeşitli fonksiyonlar kullanabilir. Bu ara işlemleri yapan fonksiyonların dışarıdan çağırılmasının hiçbir anlamı yoktur. Algıdan uzak tutmak amacıyla private bölüme yerleştirilebilirler. Sınıfı kullanacak kişi için private bölgenin incelenmesi gereksizdir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Somut, Soyut ve Arabirim Sınıflar • Kendisinden başka bir sınıf türetilmeyecek biçimde tasarlanan sınıflara somut sınıflar (concreate cleass) denir. Somut sınıflar belirli bir konuda yararlı işlemleri yaparlar. Genellikle işlevlerinin genişletilmesi biçiminde bir istek söz konusu olmaz. • Soyut sınıflar (abstract class) kendi başına bir anlamı olmayan kendisinden türetme yapılarak kullanılması zorunlu olan sınıflardır. C++’ta soyut sınıflar derleyici tarafından belirli bir syntax içimiyle doğrudan desteklenirler. • Arabirim sınıflar (interface class) en çok rastlanan sınıflardır. Kendi başlarına yararlı işlemeleri yapabilen, ancak türetme işlemine de izin verebilecek biçimde tasarlanmış sınıflardır. Arabirim sınıfları tasarlayan kişi bunları türetme durumunu göz önüne alarak tasarlamalıdır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Türetme İşlemine Birkaç Örnek • Seri port işlemlerini yapan serial isimli bir sınıf olsun. Bu sınıfın üye fonksiyonları portu set etme, okuma ve yazma gibi temel işlemleri yapsın. • Modem seri porta bağlanarak kullanılan, ve iletişimi sağlayan bir araçtır. Modemi programlamak için seri porta bilgi göndermek gerekir. Modem işlemlerini yapmak için serial sınıfından türetme uygulanabilir. Benzer biçimde laplink kablosu kullanarak seri portlar arası bilgi transferi için laplink isimli ayrı bir sınıf türetilebilir. • MFC sınıf sisteminde CWnd sınıfı genel olarak her türlü pencereyle ilgili işlem yapmak amacıyla kullanılır. Dialog pencereleri özel pencerelerdir. Yani bir pencerenin tüm özelliğini gösterir, ancak ek özelliklere de sahiptir. CDialog sınıfı CWnd sınıfından türetilmiştir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Ancak her dialog penceresi kendine özgü farklılıklara sahiptir. MFC’de ne zaman bir dialog penceresi açılacak olsa CDialog sınıfından bir sınıf türetilmeli ve dialog penceresi o sınıfla ilişkilendirilmelidir. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Bu durumda MyDialog sınıfına ilişkin bir nesne tanımlanırsa bu nesne yoluyla CWnd sınıfına ilişkin üye fonksiyonlar çağırıldığında; pencereye ilişkin temel işlemler, CDialog sınıfının üye fonksiyonları çağırıldığında dialog pencerelerine ilişkin genel işlemler ve nihayet MyDialog sınıfına ilişkin üye fonksiyonlar çağırıldığında kendi dialog penceremizle ilgili özel işlemler yapılacaktır. Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Örnek 1(Basit bir türetme örneği) #include <iostream> #include <string> using namespace std; class Teacher{ // Base class protected: // public for derived class string name; int age,numOfStudents; public: void setTeacher (const string &, int , int); void print() const; }; void Teacher::setTeacher (const string &new_name,int a,int nos) { name=new_name; age=a; numOfStudents=nos; } void Teacher::print() const // Print method of Teacher class { cout <<"Name: "<< name<<" Age: "<< age<< endl; cout << "Number of Students: " <<numOfStudents << endl; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// ***** Principal is derived from Teacher ***** class Principal : public Teacher{ // Derived class string school_name; int numOfTeachers; public: void setPrincipal(const string &, int ,int ,int, const string &); void print() const; // Print function of Principal class }; void Principal::setPrincipal(const string &new_name,int a,int nos,int not, const string &sch) { setTeacher(new_name,a,nos); numOfTeachers=not; school_name=sch; } void Principal::print() const // Print method of Principal class { Teacher::print(); // invokes the print function of the Teacher class cout <<"Name of the school: "<< school_name << endl; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// --- Main Function --- int main() { Teacher t1; Principal p1; p1.setPrincipal("Principal 1",50,100,20,"School1"); t1.setTeacher("Teacher 1",35,40); p1.print(); t1.print(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Örnek 2(Overriding members of base class) #include <iostream> using namespace std; class A{ // Base class public: int ia1,ia2; void fa1(); int fa2(int); }; class B: public A{ // Derived class public: float ia1; // overrides ia1 float fa1(float); // overloads fa1 }; // --- Methods of A --- void A::fa1() { cout << "fa1 of A has been called" << endl; } int A::fa2(int i) { cout << "fa2 of A has been called" << endl; return i; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// --- Methods of B --- float B::fa1(float f) { cout << "fa1 of A has been called" << endl; return f; } // ----- Main Function ----- int main() { B b; int j=b.fa2(1); // A::fa2 b.ia1=4; // float fa1 of B b.ia2=3; // ia2 of A. If it is public float y=b.fa1(3.14); // OK, fa1 of B is called //b.fa1(); // ERROR! fa1 of B needs a floar argument b.A::fa1(); b.A::fa1(); b.A::ia1=1; return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Örnek 3( Defult constructors in inheritance ) #include <iostream> using namespace std; //////////////////////////////////////////////////// class Parent { public: Parent() { cout << endl<< " Parent constructor"; } }; //////////////////////////////////////////////////// class Child : public Parent { public: Child() { cout << endl<<" Child constructor"; } }; // ----- Main function ----- int main() { cout << endl<<"Starting"; Child ch; // create a Child object cout << endl<<"Terminating"; return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Örnek 4(Calling the Constructor of theBase Class ) #include <iostream> using namespace std; class Teacher{ // Base class string name; int age,numOfStudents; public: Teacher(const string &); // Constructor of base }; class Principal : public Teacher{ // Derived class int numOfTeachers; public: Principal(const string &, int); }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// Body of the constructor of the base class Teacher::Teacher(const string & new_name):name(new_name) { cout << "Constructor of Teacher (Base)" << endl; } // Body of the constructor of derived class Principal::Principal(const string & new_name, int numOT) :Teacher(new_name), numOfTeachers(numOT) { cout << "Constructor of Principal (Derived)" << endl; } // ----- Main Function ----- int main() { Principal p1("Ali Bilir",20); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
Örnek 5(Constructors and destructors in a chain of classes) #include <iostream> using namespace std; class A { private: int intA; float floA; public: A(int i, float f) : intA(i), floA(f) // initialize A { cout << "Constructor A" << endl; } void display() { cout << intA << ", " << floA << "; "; } ~A() // Destructor { cout << endl << "Destructor A"; } }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
// ******* B is derived from A ******** class B : public A { private: int intB; float floB; public: B(int i1, float f1, int i2, float f2) : A(i1, f1), // initialize A intB(i2), floB(f2) // initialize B { cout << "Constructor B" << endl; } void display() { A::display(); cout << intB << ", " << floB << "; "; } ~B() // Destructor { cout << endl << "Destructor B"; } }; Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli
//******** C is derives from B *********** class C : public B { private: int intC; float floC; public: C(int i1, float f1, int i2, float f2, int i3, float f3) : B(i1, f1, i2, f2), // initialize Parent intC(i3), floC(f3) // initialize Child { cout << "Constructor C" << endl; } void display() { B::display(); cout << intC << ", " << floC; } ~C() // Destructor { cout << endl << "Destructor C"; } }; int main() { C c(1, 1.1, 2, 2.2, 3, 3.3); cout << endl<< "Data in c = "; c.display(); return 0; } Harran Üniversitesi Bilgisayar Mühendisliği Yrd.Doç.Dr.Nurettin Beşli