1 / 101

类和对象及其封装性

类和对象及其封装性. 回顾:面向对象的方法. 目的: 实现软件设计的产业化。 观点: 自然界是由实体(对象)所组成。 程序设计方法: 使用面向对象的观点来描述模仿并处理现实问题。 要求: 高度概括、分类、和抽象。. 抽象. 抽象是对具体对象(问题)进行概括,抽出这一类对象的公共性质并加以描述的过程。 先注意问题的本质及描述,其次是实现过程或细节。 数据抽象:描述某类对象的属性或状态(对象相互区别的物理量)。 代码抽象:描述某类对象的共有的行为特征或具有的功能。 抽象的实现:通过类的声明。. 抽象实例——钟表. 数据抽象:

Download Presentation

类和对象及其封装性

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 类和对象及其封装性

  2. 回顾:面向对象的方法 • 目的: • 实现软件设计的产业化。 • 观点: • 自然界是由实体(对象)所组成。 • 程序设计方法: • 使用面向对象的观点来描述模仿并处理现实问题。 • 要求: • 高度概括、分类、和抽象。

  3. 抽象 抽象是对具体对象(问题)进行概括,抽出这一类对象的公共性质并加以描述的过程。 • 先注意问题的本质及描述,其次是实现过程或细节。 • 数据抽象:描述某类对象的属性或状态(对象相互区别的物理量)。 • 代码抽象:描述某类对象的共有的行为特征或具有的功能。 • 抽象的实现:通过类的声明。

  4. 抽象实例——钟表 • 数据抽象: int Hour, int Minute, int Second • 代码抽象: SetTime(), ShowTime()

  5. 抽象实例——钟表类 class Clock { public: void SetTime(int NewH, int NewM, int NewS); void ShowTime(); private: int Hour,Minute,Second; };

  6. 抽象实例——人 • 数据抽象: char *name,char *sex,int age,int id • 代码抽象: 生物属性角度:GetCloth(), Eat(), Step(),… 社会属性角度:Work(), Promote() ,…

  7. 封装 将抽象出的数据成员、代码成员相结合,将它们视为一个整体。 • 目的是曾强安全性和简化编程,使用者不必了解具体的实现细节,而只需要通过外部接口,以特定的访问权限,来使用类的成员。 • 实现封装:类声明中的{}

  8. 外部接口 边界 封装 • 实例: class Clock { public: void SetTime(int NewH,int NewM, int NewS); void ShowTime(); private: int Hour,Minute,Second; }; 特定的访问权限

  9. 类与对象的声明和定义 1. 类的定义 类的定义: • 成员函数的定义 • 数据成员的定义

  10. 2、声明类的一般形式为 class 类名 { private: 私有数据和函数 public: 公有数据和函数 protected: 保护数据和函数 };

  11. 3、说明 (1)类声明以关键字class开始,其后跟类名。 (2)类所声明的内容用花括号括起来,这一对花括号“{ }”之间的内容称为类体。 (3)类中定义的数据和函数分别是数据成员和成员函数

  12. 4、访问权限 (1)用于控制对象的某个成员在程序中的可访问性 (2)关键字private 、public和protected 定义的成员访问权限分别是私有、公有和保护的,把这些成员分别叫做私有成员、公有成员和保护成员 (3)所有成员默认声明为private权限。

  13. 例: 定义一个Person类 class Person {private: char Name[20]; int Age; char Sex; public: void Register(char *name, int age, char sex); void ShowMe(); };

  14. 成员函数的定义 返回类型 类名∷成员函数名(参数列表) { 成员函数的函数体//内部实现 } 其中“∷”是作用域运算符,“类名”是成员函数所属类的名字,“∷”用于表明其后的成员函数是属于这个特定的类。换言之,“类名∷成员函数名”的意思就是对属于“类名”的成员函数进行定义,而“返回类型”则是这个成员函数返回值的类型。余下的工作就是定义成员函数的函数体。

  15. 二、对象的定义 定义格式: <类名> <对象1>,<对象2>,… ; 例如:Person person1,person2;

  16. 3 成员函数 一、成员函数的定义 格式:<类型> <类名>::<函数名>(<参数表>) { <函数体> } 二、内联成员函数 使用关键字inline将成员函数定义为内联函数 例如: inline void Person:: Register(char *name, int age, char sex) {……;}

  17. 例: Person类成员函数的定义 void Person:: Register(char *name, int age, char sex) { strcpy(Name, name); Age = age; Sex = (sex == 'm'? 'm':‘f'); } void Person:: ShowMe() { cout << Name << '\t' << Age << '\t' << Sex << endl; }

  18. 4 对象的访问 1、在类的作用域内,成员函数直接访问同类中的数据成员 2、在类的作用域外,对象访问其数据成员或成员函数需使用运算符“.” 3、在类的作用域外,禁止直接访问一个对象中的私有成员 4、同类对象之间可以整体赋值 5、对象用作函数的参数时属于赋值调用;函数可以返回一个对象

  19. 例 :完整的人事资料输入输出程序 int main() { char name[20], sex; int age; Person person1, person2; cout << "Enter a person's name, age and sex:"; cin >> name >> age >> sex; person1.Register(name, age, sex);

  20. cout << "person1: \t"; person1.ShowMe(); //调用类的成员函数输出 person1.Register("Zhang3", 19, 'm'); cout << "person1: \t"; person1.ShowMe(); //调用类的成员函数输出 person2 = person1; //对象之间的赋值 cout << "person2: \t"; person2.ShowMe(); //调用类的成员函数输出 return 0; }

  21. 例: 简单的日期类 定义一个最简单的日期类,仅包含说明日期的数据成员。 // Example : 最简单的日期类 #include <iostream> using namespace std; class Date { public: int day, month, year; };

  22. int main() { Date date1, date2; //声明2个日期对象 cin >> date1.day >> date1.month >> date1.year; cout << date1.month << “-“ << date1.day << “-“ << date1.year << endl; cin >> date2.day >> date2.month >> date2.year; cout << date2.month << “-“ << date2.day << “-“ << date2.year << endl; return 0; }

  23. 例: 定义最简单的日期类,用函数实现对象的输入输出操作。 #include <iostream> using namespace std; class Date { public: int day, month, year; }; void set_date(Date& d); void show_date(Date d);

  24. int main() { Date date1, date2; //声明2个日期对象 set_date(date1); //使用全局函数操作数据成员 show_date(date1); set_date(date2); show_date(date2); return 0; }

  25. void set_date(Date& d) { cin >> d.day >> d.month >> d.year; } void show_date(Date d) { cout << d.month << "-" << d.day << "-" << d.year << endl; }

  26. 例定义简单的完整意义上的日期类 #include <iostream> using namespace std; class Date { int day, month, year; public: void init(int,int,int); //初始化数据成员 void print_ymd(); void print_mdy(); };

  27. void Date::init(int yy, int mm, int dd) { month = ( mm >= 1 && mm <= 12 ) ? mm : 1; year = ( yy >= 1900 && yy <= 2100 ) ? yy : 1900; day = ( dd >= 1 && dd <= 31 ) ? dd : 1; } void Date::print_ymd() { cout << year << "-" << month << "-" << day << endl;} void Date::print_mdy() { cout << month << "-" << day << "-" << year << endl;}

  28. int main() { Date date1,date2; date1.print_ymd(); //未初始化时的情况 date1.init(2006,3,28); //正确的初始化数据 date1.print_ymd(); date1.print_mdy(); date2.init(2006,13,38); //错误的初始化数据 date2.print_ymd(); date2.print_mdy(); return 0; }

  29. 程序设计举例 • 点类和圆类 • 在二维平面空间上,使用(x,y)坐标可以确定一个点,确定了圆心坐标和半径可以确定一个圆。声明一个点类,并使用这个点类的对象为数据成员声明圆类。

  30. // Point.h文件 Point类的声明 #ifndef POINT_H #define POINT_H class Point { int x, y; //点的x和y坐标 public: void SetPoint( int, int ); // 设置坐标 int GetX() { return x; } // 取x坐标 int GetY() { return y; } // 取y坐标 void Print(); //输出点的坐标 }; #endif

  31. // Point.cpp文件 Point类的成员函数定义 #include <iostream> using namespace std; #include "point.h" void Point::SetPoint( int a, int b ) { x = a; y = b; } void Point::Print() { cout << '[' << x << ", " << y << ']';}

  32. // Circle.h文件 Circle类的声明 #ifndef CIRCLE_H #define CIRCLE_H #include <iostream> using namespace std; #include "point.h" class Circle { double Radius; Point Center;

  33. public: void SetRadius(double); //设置半径 void SetCenter(Point); //设置圆心坐标 double GetRadius(); //取半径 Point GetCenter(); //取圆心 double Area(); //计算面积 void Print(); //输出圆心坐标和半径 }; #endif

  34. // Circle.cpp文件 Circle类的成员函数定义 #include <iostream> using namespace std; #include "circle.h" void Circle::SetRadius(double r) { Radius = ( r >= 0 ? r : 0 ); } void Circle::SetCenter(Point p) { Center = p; } Point Circle::GetCenter() { return Center; }

  35. double Circle::GetRadius() { return Radius; } double Circle::Area() { return 3.14159 * Radius * Radius; } void Circle::Print() { cout << "Center = "; Center.Print(); cout << "; Radius = " << Radius << endl; }

  36. // Example.cpp文件: Circle Demo #include <iostream> using namespace std;#include "point.h" #include "circle.h" int main() { Point p,center; p.SetPoint(30,50); center.SetPoint(120,80); Circle c; c.SetCenter(center); c.SetRadius(10.0);

  37. cout << "Point p: "; p.Print(); cout << "\nCircle c: "; c.Print(); cout << "The centre of circle c: "; c.GetCenter().Print(); cout << "\nThe area of circle c: " << c.Area() << endl; return 0; }

  38. 构造函数 • 构造函数(constructor) • 用于对对象进行初始化的一个或一组函数。 • 构造函数是特殊的公有成员函数,其特征如下: 1.函数名与类名相同。 2.构造函数无函数返回类型说明。 3.在新的对象被建立时,该对象所属的类的构造函数自动被调用。 4.构造函数可以重载。它们由不同的参数表区分。

  39. 对象的初始化和构造函数 例: 定义一个带构造函数的日期类。 #include <iostream> using namespace std; class Date { int day,month,year; public: Date(); //构造函数 void init(int,int,int); //对数据成员赋值 void print_ymd(); void print_mdy(); };

  40. Date::Date() { year = 1900; month = 1; day = 1; }

  41. void Date::init(intyy, int mm, intdd) { month = ( mm >= 1 && mm <= 12 ) ? mm : 1; year = ( yy >= 1900 && yy <= 2100 ) ? yy : 1900; day = ( dd >= 1 && dd <= 31 ) ? dd : 1; } void Date::print_ymd() { cout << year << "-" << month << "-" << day << endl;} void Date::print_mdy() { cout << month << "-" << day << "-" << year << endl;}

  42. int main() { Date date1, date2; //创建2个日期类对象 date1.print_ymd(); //输出使用init赋值前对象的内容 date2.print_ymd(); date1.init(2006, 3, 28); //正确的赋值数据 date1.print_ymd(); date1.print_mdy(); date2.init(2006,13,38); //错误的赋值数据 date2.print_ymd(); date2.print_mdy(); return 0; }

  43. 二、构造函数的重载 构造函数重载时,这些构造函数的参数的个数或类型不同 例: 定义一个带重载构造函数的日期类。 #include <iostream> using namespace std; class Date { int day,month,year; public: Date(); //构造函数 Date(int,int,int); //构造函数 void init(int,int,int); void print_ymd(); void print_mdy(); };

  44. Date::Date() { year = 1900; month = 1; day = 1; } Date::Date(int yy, int mm, int dd) { init(yy,mm,dd); }

  45. void Date::init(intyy, int mm, intdd) { month = ( mm >= 1 && mm <= 12 ) ? mm : 1; year = ( yy >= 1900 && yy <= 2100 ) ? yy : 1900; day = ( dd >= 1 && dd <= 31 ) ? dd : 1; } void Date::print_ymd() { cout << year << "-" << month << "-" << day << endl;} void Date::print_mdy() { cout << month << "-" << day << "-" << year << endl;}

  46. int main() { //使用2个不同的重载构造函数创建2个日期类对象 Date date1, date2(2006,3,28); date1.print_ymd(); date2.print_ymd(); date1.init(2006,3,28); date1.print_ymd(); date2.init(2006,4,8); date2.print_ymd(); return 0; }

  47. 三. 数据成员的初始化 1.在构造函数的函数体中进行初始化。 2.在构造函数的头部初始化。 3.混合初始化 4. 使用默认参数初始化。

  48. 1. 在构造函数的函数体中初始化 class Person { char Name[20]; int Age; char Sex; public: Person() { strcpy(Name, "XXX"); Age = 0; Sex = 'm'; } } 例如, 当遇到声明 Person personl; Person person2;

  49. 2.在构造函数的头部初始化。 其格式为: <类名>::<构造函数>(<参数表>):<变量1>(<初值1>), …, <变量n>(<初值n>) { …… } 例如 Person::Person(): Age(0),Sex('m') { }

  50. 3.混合初始化 。 例如 Person::Person(): Age(0),Sex('m') { strcpy(m_strName, “XXX”); }

More Related