24
Нийлмэл удамшил Р.Мижиддорж, КМТС

Lecture 4 нийлмэл удамшил

Embed Size (px)

DESCRIPTION

OOP, ОХП, Нийлмэл удамшил, бүрдмэл харьцаа

Citation preview

Нийлмэл удамшилР.Мижиддорж, КМТС

Amphibian

Driver- license- Year of approval

Conductor- Account number

TaxiDriver- area

House Boat

Houseboat

Удамшил нь нэг класс дээр үндэслэн өөр класс үүсгэх юм. Хэд хэдэн классаас өөр класс удамшуулах талаар авч үзье. Хэд хэдэн эх класстай байна гэдэг нь хэд хэдэн классын шинж чанарыг агуулсан класс үүсгэх юм.

Байгуулагч функц аргумент шаарддаг удамшсан классын обьект зарлахад удамшсан класс нь эх классын байгуулагч функцийг аргументаар хангаж өгөх хэрэгтэй. Энэ нь удамшлын үед яригдах гол дүрэм юм. Иймд аргументаар хангаж өгөх асуудал заавал гарч ирнэ. Энэ үед байгуулагч функцийн анхны утга тогтоох жагсаалтыг хэрэглэх нь маш оновчтой шийдэл болдог юм.

Нийлмэл удамшил нь аливаа удамшсан класс нь нэгээс олон үндсэн класстай байхыг зөвшөөрдөг. Жишээ нь: class Date { protected: public: void Display(); int day; Date(); Date Get(); int month; ~Date(); void Set();

int year; }; class Time {protected: public: void Display(); int hour; Time(); Time Get();

int minute; ~Time(); void Set(); int second; };

 class DateTime :public Date, public Time{ int digital; public: void Display(); }; DateTime –класс нь Date, Time –ийн

гишүүдийг агуулна.

DateTime watch; // watch; объект

Одоо watch.Display(); гэж Display –г дуудаж болно. Хэрэв Display –г дахин тодорхойлоогүй бол дээрх үйлдэл нь эргэлзээтэй.

Үүнийг шийдэхдээ watch.Date::Display();

эсвэлwatch.Time::Display();

 

Виртуал үндсэн классCPerson

m_name : stringm_age : int

GetName() costGetAge() constSetName(string)SetAge(int)Print() const

CEngineer

m_nEngType : int

GetEngType()SetEngType(int)Print() const

CSalaried

m_nSalary : int

GetSalary()SetSalary(int)Print() constCSalariedEng

m_nDept : int

GetDept()SetDept(int)Print() const

Хүн

Цалинтай хүнИнженер

Виртуал үндсэн классCPerson

m_name : stringm_age : int

GetName() costGetAge() constSetName(string)SetAge(int)Print() const

CEngineer

m_nEngType : int

GetEngType()SetEngType(int)Print() const

CSalaried

m_nSalary : int

GetSalary()SetSalary(int)Print() constCSalariedEng

m_nDept : int

GetDept()SetDept(int)Print() const

Хүн

ЦалинтайИнженер

CSalariedEng классын байгуулагч функц нь өөрийн эх классуудыхаа байгуулагч функцийг анхны утгаар хангах ёстой. Өөрөөр хэлбэл CPerson –н хоёр хуулбарыг агуулах ба энэ 2 хуулбар нь хоорондоо зөрчилдөж магадгүй.

Виртуал үндсэн класс

CPerson

m_name : stringm_age : int

GetName() costGetAge() constSetName(string)SetAge(int)Print() const

CEngineer

m_nEngType : int

GetEngType()SetEngType(int)Print() const

CSalaried

m_nSalary : int

GetSalary()SetSalary(int)Print() const

CSalariedEng

m_nDept : int

GetDept()SetDept(int)Print() const

CPerson

m_name : stringm_age : int

GetName() costGetAge() constSetName(string)SetAge(int)Print() const

CSalariedEng классын байгуулагч функц нь өөрийн эх классуудыхаа байгуулагч функцийг анхны утгаар хангах ёстой. Өөрөөр хэлбэл CPerson –н хоёр хуулбарыг агуулах ба энэ 2 хуулбар нь хоорондоо зөрчилдөж магадгүй.

CSalariedEng классын байгуулагч функц нь өөрийн эх классуудыхаа байгуулагч функцийг анхны утгаар хангах ёстой. Ө.х CPerson –н хоёр хуулбарыг агуулах ба энэ 2 хуулбар нь хоорондоо зөрчилдөж магадгүй.

Нийлмэл удамшлын үед анхдагч үндсэн классын (CPerson) хуулбар нь ач класс (CSalariedEng)-д ганц байх ёстой. Үүнийг virtual түлхүүр үгээр шийддэг.

class CPerson {. . .};class CEngineer : virtual public CPerson{. . . };

одоогоор virtual түлхүүр үг ямар ч ач холбогдолгүй.

class CSalaried : virtual public CPerson{. . . };

Харинclass CSalariedEng : public CEngineer, public CSalaried {.

. . };

гэж нийлмэл удашил зарлах үед CPerson -н зөвхөн нэг хуулбар үүсэх ёстой.

Person.dev

class CPerson { protected: int age; public: CPerson(int a){ age=a;} };class CEngineer :virtual public CPerson { protected: int m_nEngType; public: CEngineer(int d, int a): CPerson(a){

m_nEngType =d;} }; class CSalaried :virtual public CPerson{ int m_nSalary; public: CSalaried (int t, int a):CPerson(a)

{m_nSalary =t; } } ; Person.dev

class CSalariedEng :public CEngineer , public CSalaried {

int m_nDept;public: CSalariedEng (int s, int t, int d, int a): m_nDept(s), CPerson(a), CEngineer(d), CSalaried(t){};};CSalariedEng байгуулагч функц нь зөвхөн өөрийгөө

байгуулаад зогсохгүй өөрийн эх классуудыг цаашилбал CPerson- классын хэсгийг өөрөө үүсгэдэг.

Person.dev

CSalariedEng –н объект үүсэх үед virtual түлхүүр үг нь CEngineer ба CSalaried классуудад өөрсдийн эх классийг үүсгэх шаардлагaгүй гэдгийг хэлдэг.

Учир нь virtual түлхүүр үгийг ашигласнаар CSalariedEng нь анхдагч үндсэн (CPerson) классыг өөрөө үүсгэдэг.

CSalariedEng sengr(173,30000,10,43);Харин CEngineer ба CSalaried –н объект

тодорхойлбол CEngineer engr(10,43); CSalaried sman(30000, 43); объект бүр үндсэн

классын байгуулагч функцыг дуудах болно. Эдгээр объектын хувьд virtual түлхүүр үг нь ач холбогдолгүй юм. Харин CSalariedEng-н объект тодорхойлох үед түүний хэрэглээ гарч байна.

Person.dev

sengr(173,30000,10,43);

sengr зөрчилгүй Sengr-н нас хоёр хувь байгаа нь яваандаа

зөрчил үүсгэж магадгүй

43

43

10

30000

173

43

10

30000

173

Классуудын хамаарал

Хоёр класс хоорондоо харилцан хамаарах хоёр ерөнхий зүйл байна:

1. Удамшил (“is-a” харилцаа, . . . a kind of. . .)(Every employee is a person. Ажилчин бүр хүн.)

2. Бүрдмэл (“has-a” харилцаа)(Every person has date of birth. Хүн бүр төрсөн өдөртэй.)

Хүн

Ажилчин

Багш

Классуудын хамаарал, энгийн удамшил (Багш нар)

Хүн

Классуудын хамаарал, нийлмэл удамшил (Цалинтай инженерүүд)

Цалинтай хүн

Инженер

Цалинтай инженер

Бүрдмэл харьцаа

Өөр класс төрлийн нэг буюу түүнээс олон объект гишүүн өгөгдөлтэй байх

Класс хоорондын харилцаа нь “has-a” Гишүүн объектийн байгуулагчийн

аргументийг классын байгуулагчийн толгойн хэсэгт тодорхойлно

Бүрдмэл классын байгуулагч аргументдаа объект авах

Бүрдмэл классын байгуулагч аргументдаа объектийн утгыг авах

Классын гишүүн объект нь зарлагдсан дарааллаараа байгуулагдана

Утга олголт (= оператор дахин тодорхойлох хэрэгцээ

гарна)

Бүрдмэл харьцаа

class List { public: List(); void addToFront(int); int firstElement(); int length(); int includes(int); void remove(int); private: //бүхэл тоо хадгалах өгөгдлийн

бүтэц };

Бүрдмэл харьцаа

class Set { public: Set(); void add(int); int size(); int includes(int); private: List data; // бүрдмэл харьцаа};

Бүрдмэл харьцаа

int Set::size() { return data.length(); } int Set::includes(int newValue) { return data.includes(newValue); } void Set::add(int newValue) { if( ! includes(newValue) )

data.addToFront(newValue); // үгүй бол // олонлог элементийг нэг л

удаа // хадгалах тул үйлдэл хийхгүй

}Set::Set() : data() { // Олонлогийн элемент}

Бүрдмэл харьцаа

class_agr.cpp

class_comp.cpp

Composition: Машин бүр хөдөлгүүртэй. (байхгүй байж болохгүй)

Aggregation: Машин зорчигчтой байж болно. (зорчигчгүй байж болно)

МАШИН ХӨДӨЛГҮҮР

МАШИН ЗОРЧИГЧ