Bài tập thực hành Lập trình hướng đối tượng

 + Phần này sẽ giúp các bạn hiểu rõ hơn về các thành phần của lớp như hàm thành viên(Member Functions) , biến thành viên (data members) cũng như cách khai báo và truy cập lên các thành phần đó

 + Thực hiện các bước sau:

+ Tạo một file mới.

 

doc43 trang | Chuyên mục: Lập Trình Hướng Đối Tượng | Chia sẻ: dkS00TYs | Lượt xem: 5267 | Lượt tải: 1download
Tóm tắt nội dung Bài tập thực hành Lập trình hướng đối tượng, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
ne base class
{
	private:
	char name[25];
	int roll_no;
	char sex;
	public:
	void getinfo();
	void display();
};
class academics	//second base class
{
	private:
	char course_name[25];
	int semester;
	char grade[3];
	public:
	void getinfo();
	void display();
};
class stud_scholarship: public person_data, public academics
{
	private:
	float amount;
	public: 
	void getinfo();
	void display();
};
void person_data::getinfo()
{
	cout << “Ten: “;
	cin>> name;
	cout<<”So: “;
	cin>>roll_no;
	cout<<”Gioi tinh(F/M) : “;
	cin>> sex;
}
void person_data:: display()
{
	cout<<name<<”\t”;
	cout<<roll_no<<”\t”;
	cout<<sex<<”\t”;
}
void academics::getinfo()
{
	cout<<”Ten khoa (BA/MBA/MCA etc)? “;
	cin>>course_name;
	cout<< “Hoc ky (1/2/3/...)? “;
	cin>>semester;
	cout<<”muc do (A,B,B+,B-..) ? ”;
	cin>>grade;
}
void academics::display()
{
	cout<<course_name<<”\t”;
	cout<<semester<<”\t”;
	cout<<grade<<”\t”;
}
void stud_scholarship::getinfo()
{
	person_data::getinfo();
	academics::getinfo();
	cout<<”Su ho tro “;
	cin>>amount;
}
void stud_scholarship::display()
{
	person_data::display();
	academics::display();
	cout<<setprecision(2);
	cout<<amount<<endl;}
void main()
{
	clrscr();
	stud_scholarship obj;
	cout<<”Nhap cac thong tin sau: “<<endl;
	obj.getinfo();
	cout<<endl;
	cout<<”Ten So Gioi tinh Khoa Hoc ky Muc do”;	cout<<”Amount”<<endl;
	obj.display();
}
Lưu file với tên “multi52.cpp”
Dịch và chạy chương trình
Đóng file “danag411.cpp”
Trong chương trình trên, các lớp cơ sở có hàm trùng tên vì vậy khi lớp dẫn xuất gọi các hàm này phải chỉ rõ là hàm dược gọi của lớp nào (xem hàm getinfo và hàm display của lớp dẫn xuất).
Hàm khởi tạo trong kế thừa
Khi trong lớp cơ sở và lớp dẫn xuất có hàm khởi tạo (constructors) thì lớp cơ sở sẽ được khởi tạo trước với hàm khởi tạo mặc định hoặc hàm có tham số tùy thuộc vào khai báo ở trong lớp dẫn xuất. 
Tạo file mới
Gõ đoạn chương trình sau
#include
#include
class Alpha
{
	public:
	Alpha()
	{
	cout<< “Ham khoi tao cua lop Alpha”<<endl;
	}
};
class Beta:public Alpha
{
	public:
	Beta():Alpha()
	{
	cout<< “Ham khoi tao cua lop Beta, ke thua tu lop Alpha”	<<endl;
	}
};
class Gamma: public Alpha
{
	public:
	Gamma():Alpha()
	{
	cout<< “Ham khoi tao lop Gamma, ke thua thu lop Alpha”
	<<endl;
	}
};
class Delta: public Gamma, public Beta
{
	Beta b; //base class object
	public:
	Delta():Gamma(),Beta()
	{
	cout<< “Ham khoi tao lop Delta, ke thua thu lop Beta ”
	<< “va lop Gamma, \n”
	<< “co mot doi tuong Beta o trong “
	<<endl;
	}
};
void main()
{
	clrscr();
	cout<<”Khai bao mot doi tuong cua lop Alpha \n”;
	Alpha aa;
	cout<<endl;
	cout<<”Khai bao mot doi tuong cua lop Beta \n”;
	Beta bb;
	cout<<endl;
	cout<<”Khai bao mot doi tuong cua lop Gamma \n”;
	Gamma cc;
	cout<<endl;
	cout<<”Khai bao mot doi tuong cua lop Delta \n”;
	Delta dd;
	cout<<endl;
}
Lưu file với tên “multi53.cpp”
Dịch và chạy chương trình
Màn hình kết quả như sau:
Khai bao mot doi tuong cua lop Alpha
Ham khoi tao cua lop Alpha
Khai bao mot doi tuong cua lop Beta
Ham khoi tao cua lop Alpha
Ham khoi tao cua lop Beta, ke thua tu lop Alpha
Khai bao mot doi tuong cua lop Gamma
Ham khoi tao cua lop Alpha
Ham khoi tao lop Gamma, ke thua thu lop Alpha
Khai bao mot doi tuong cua lop Delta
Ham khoi tao cua lop Alpha
Ham khoi tao lop Gamma, ke thua thu lop Alpha
Ham khoi tao cua lop Alpha
Ham khoi tao cua lop Beta, ke thua tu lop Alpha
Ham khoi tao cua lop Alpha
Ham khoi tao cua lop Beta, ke thua tu lop Alpha
Ham khoi tao lop Delta, ke thua thu lop Beta va lop Gamma,
co mot doi tuong Beta o trong
Đóng file “danag411.cpp”
Trong chương trình trên các bạn sẽ thấy được thứ tự các hàm khởi tạo được gọi như thế nào.
Bµi thùc hµnh:
BÀI THỰC HÀNH SỐ 6
Môc tiªu:
	+ Thực hành cách viết chương trình có sử dụng cơ chế đa hình(polymorphism).
	+ Làm rõ các khái niệm: hàm ảo, hàm thuần ảo, và hàm hủy ảo (Virtual destructor).
BÀI TẬP THỰC HÀNH 	
6.1 Cơ chế đa hình (Polymorphism).
6.2 Hàm ảo (Virtual functions).
6.3 Hàm thuần ảo.
6.4 Hàm hủy ảo(Virtual destructors).
6.1 Cơ chế đa hình (Polymorphism).
Cơ chế đa hình trong C++ là cơ chế cho phép hành vi đối tượng có thể có nhiều thể hiện khác nhau tùy thuộc vào lớp thực chất mà đối tượng đó thuộc về. Khả năng cho phép một chương trình sau khi đã biên dịch có thể có nhiều diễn biến xảy ra là một trong những thể hiện của tính đa hình – tính muôn màu muôn vẻ – của chương trình hướng đối tượng, một thông điệp được gởi đi (gởi đến đối tượng) mà không cần biết đối tượng nhận thuộc lớp nào. Để thực hiện được tính đa hình, các nhà thiết kế C++ cho chúng ta dùng cơ chế kết nối động (dynamic binding) thay cho cơ chế kết nối tĩnh (static binding) ngay khi chương trình biên dịch được dùng trong các ngôn ngữ cổ điển như C, Pascal, 
6.2 Hàm ảo (Virtual functions).
Hàm ảo là hàm phải được mô tả trong lớp cơ bản, Trước hàm ảo phải có từ khoá virtual. Ta xét ví dụ sau:
#include 
#include 
#include 
class person
{
	protected:
	char *name;
	public:
	person(char *n) { name = n;}
	virtual void print() // hàm ảo
	{
	cout << “My name is :”<<name << endln;
}
};
class foreigner : public person
{
	public:
	foreigner(char *n) : person(n) { }
void printf()
	{
	cout <<ll mio nome e” <<name <<endln;
}
};
class alien : public person
{
	public:
	alien(char *n) :person(n){ }
	void print()
	{
	cout <<”&*^*&%& **^@<<name<<endln;
	cout << sorry, there’s a communication problem”;
}
};
void main()
{
	clrscr();
	person* p1;
	person *p2;
	p1 = new person(“Jack”);
	p2 = new foreigner(“Maria”);
	cout <<”Introducing a Person:” <<endln;
	p1->print();
	cout <<”Introducing a Foreigner:” <<endln;
	p2->print();
	p1 = new foreigner(“Al Pacino”);
	cout << “Reintroducing the Person:” << endln;
	p1 ->print();
	person* p3;
	p3 = new alien(“Martian”);
	cout << “Introducing a alien:” << endln;
	p3 ->print();	
}
Kết quả sau khi chạy chương trình:
	Introducing the Person:
	My name is Jack
	Introducing the Foreiger:
	ll mi o nome a Maria
 Reintroducing the person:
	ll mio nome e Al Pacino
	Introducing the alien:
 &*^*&%& **^@ Martian
	Sorry there’s a communication problem
Trong ví dụ trên ta thấy cả hai lớp dẫn xuất đều có hàm print như trong lớp cơ bản của chúng, hàm print trong lớp person là một hàm ảo. Ban đầu cả hai con trỏ p1 và p2, p3 đếu có kiểu person nhưng sau đó p1 lại thực sự trỏ đến một đối tượng kiểu person trong khi p2 lại trỏ đến một đối tượng kiểu foreigner và p3 trỏ đến đối tượng kiểu alien. Khi thực hiện p2 không gọi hàm print của lớp person mà gọi hàm print của lớp foreigner , và p3 gọi hàm print của lớp alien. Đây chính là cơ chế đa hình mà ta đã nói ở trên.
6.3 Hàm thuần ảo.
 Hàm thuần ảo là hàm ảo được mô tả bằng cách gán giá trị 0 cho hàm. Một lớp được gọi là lớp trừu tượng nếu trong lớp tồn tại một hàm ảo và không thể dùng lớp này để định nghĩa một đối tượng.
Xét chương trình sau:
#include 
#include 
class format
{
	public;
	void display_form();
	virtual void header() 
{
 cout << this is a header\n”;
}	
virtual void body() = 0; // hàm thuần ảo
virtual void footer()
 {
	cout << “this is a footer\n\n”;
}	
}
void Format :: display_form()
{
	header();
	for( int index = 0;index <3 ; index ++)
	{
	body();
}
footer();
}
class MyForm : public Format
{
	public:
	void body() { cout << “This is the new body of text\n”;}
	void footer(){ cout << This is the new footer\n”;}
};
void main()
{	
	clrscr();
	Format* first_form = new MyForm;
	First_form->display_form();
}
6.4 Hàm hủy ảo(Virtual destructors).
Hàm hủy là hàm được gọi một cách tự động để thực hiện một số công việc nào đó mà người lập trình cần khi đối tượng bị hủy , chẳng hạn hàm hủy dùng để giải phóng bộ nhớ một cách tự động khi đối tượng bị hủy. Tuy nhiên bình thường thì hàm hủy của lớp dẫn xuất sẽ không được gọi mà chỉ có hàm hủy của lớp cơ bản được gọi , nên trong một số trường hợp ta không thể dùng hàm ảo trong một lớp dẫn xuất để thực hiện các thao tác mà ta cần khi một làm khi một đối tượng của lớp mày bị hủy. Vấn đền này được giải quyết bằng cách dúng hàm hủy ảo. Hàm hủy của lớp cơ bản sẽ là một hàm ảo, các lớp dẫn xuất sẽ có hàm hủy riêng và khi đối tượng bị hủy ,hàm hủy của lớp cơ bản và lớp dẫn xuất đều sẽ được gọi.
	Xét ví dụ sau;
#include 
class Base
{
public:
 ~Base()
 { 
cout<<"~Base"<<endl;
 }
 };
class Derived:public Base
{
public:
~Derived()
{
cout<<"~Derived"<<endl;
}
};
int main()
{
Base *B;
B = new Derived;
delete B;
return 0;
}
Kết quả khi thực hiện :
	~Base
Như vậy ta thấy chỉ có hàm hủy của lớp cơ bản được gọi , còn hàm hủy của lớp dẫn xuất không được gọi . 
Bây giờ ta sửa lại chương trình trên như sau:
#include 
class Base
{
public:
virtual ~Base()
 {
 cout<<"~Base"<<endl;
 }
 };
class Derived:public Base
{
public:
virtual ~Derived()
{
cout<<"~Derived"<<endl;
}
};
int main()
{
Base *B;
B = new Derived;
delete B;
return 0;
}
Khi đó kết quả của chương trình sẽ là ;
	~ Base
	~Derived
Bµi tËp lµm thªm
	 Xây dựng các lớp theo sơ đồ sau đây :
HINH
H_TRON
H_CHUNHAT
Trong đó HINH là lớp cơ bản, H_TRON, H_CHUNHAT là các lớp dẩn xuất, lớp hình có các hàm ảo thuần ảo 
	virtual void Ve() // hàm vẽ hình ra màn hình 
	virtual int TinhDienTich() // hàm tính diện tích 
Các lớp dẫn xuất sẽ viết lại các hàm trên để vẽ hay tính diện tích cho thích hợp.

File đính kèm:

  • docBài tập thực hành Lập trình hướng đối tượng.doc
Tài liệu liên quan