Upload
mijiddorj-renchin-ochir
View
921
Download
11
Embed Size (px)
DESCRIPTION
OOP, ОХП, Нийлмэл удамшил, бүрдмэл харьцаа
Citation preview
Удамшил нь нэг класс дээр үндэслэн өөр класс үүсгэх юм. Хэд хэдэн классаас өөр класс удамшуулах талаар авч үзье. Хэд хэдэн эх класстай байна гэдэг нь хэд хэдэн классын шинж чанарыг агуулсан класс үүсгэх юм.
Байгуулагч функц аргумент шаарддаг удамшсан классын обьект зарлахад удамшсан класс нь эх классын байгуулагч функцийг аргументаар хангаж өгөх хэрэгтэй. Энэ нь удамшлын үед яригдах гол дүрэм юм. Иймд аргументаар хангаж өгөх асуудал заавал гарч ирнэ. Энэ үед байгуулагч функцийн анхны утга тогтоох жагсаалтыг хэрэглэх нь маш оновчтой шийдэл болдог юм.
Нийлмэл удамшил нь аливаа удамшсан класс нь нэгээс олон үндсэн класстай байхыг зөвшөөрдөг. Жишээ нь: 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() { // Олонлогийн элемент}
Бүрдмэл харьцаа