面向对象
日常生活中,我们习惯对事物进行分类,那么怎么把分类的思想引入程序设计呢?
于是C++引入面向对象的编程:类和对象
注意以下问题:
-
(1)类一定存在实际的对象吗?
不一定,eg:恐龙有很多分类,人的老祖宗对猿人分类:智人、直立人等,这些在现实生活中已经找不到活体对象,因此不一定是实际的对象。 -
(2)类对应的对象数目是确定的吗?
不确定的,也可能确定的
eg:不确定:东北虎的存有量,没法去统计
确定的:从历史上来看,皇帝这一类始终都只有一个。 -
(3)类都来源于生活吗
不一定,类也可来源于经验和思想 -
(4)类之间都是独立的吗?类之间存在关系吗?
类不是独立的,类之间是相互关联的
eg:电脑,CPU类和外设各种类,不同匹配类型组成不同配置的电脑对象。 -
(5)对象实体一定只能属于一个类吗?
不一定,根据不同分类可能会属于不同的类。但是一定能找到对应的一个类模型是存在的。
eg:人分为男人女人,但是根据年龄分又可分为:成年人,未成年人 -
(6)对象实体可能完全相同吗?
不可能,正如世界上没有两片相同的树叶
类之间的关系:继承 / 组合
类的表示
类的封装
#include <stdio.h>
struct Biology
{
bool living;
};
struct Animal : Biology
{
bool movable;
void findFood()
{
}
};
struct Plant : Biology
{
bool growable;
};
struct Beast : Animal
{
void sleep()
{
}
};
struct Human : Animal
{
void sleep()
{
printf("I'm sleeping...\n");
}
void work()
{
printf("I'm working...\n");
}
};
struct Girl : Human//定义了一个Girl类
{
private: //私有访问
int age;//成员变量属性:age
int weight;//成员变量属性:weight
public: //公共访问
void print()
{
age = 22;
weight = 48;
printf("I'm a girl, I'm %d years old.\n", age);
printf("My weight is %d kg.\n", weight);
}
};
struct Boy : Human//定义了一个Boy类
{
private:
int height;
int salary;
public:
int age;
int weight;
void print()//因此print()函数是类的内部成员函数,因此可以直接访问私有区域的变量和调用函数
{
height = 175;
salary = 9000;
printf("I'm a boy, my height is %d cm.\n", height);
printf("My salary is %d RMB.\n", salary);
}
};
int main()
{
Girl g;//创建了一个对象g,对象g属于Girl这个类
Boy b;
//printf("g.age = %d\n", g.age); 错误:age为私有,不可外界访问
g.print();//g.printf为public,外界可访问公共的成员变量和成员函数
b.age = 19;
b.weight = 120;
//b.height = 180; 错误:为私有,main为外部
b.print();
return 0;
}
类成员的作用域
- 类的作用域是指类中的成员变量和成员函数的作用域。成员的作用域范围是:
只在整个类定义的struct{作用域范围}
的内部,和访问等级private和public无关
。 - 外部(外界)想访问类的成员时,必须先定义类的对象,通过对象.类成员访问
类public里的成员
。
#include <stdio.h>
int i = 1;
struct Test
{
private:
int i;
public:
int j;
int getI()
{
i = 3;
return i;
}
};
int main()
{
int i = 2;
Test test;
test.j = 4;
printf("i = %d\n", i); // i = 2;
printf("::i = %d\n", ::i); // ::i = 1;
// printf("test.i = %d\n", test.i); // Error
printf("test.j = %d\n", test.j); // test.j = 4
printf("test.getI() = %d\n", test.getI()); // test.getI() = 3
return 0;
}
类的定义:class
C语言中,struct结构体定义的是一个变量的集合,结构体中不能定义函数;
而C++中,struct中即可以定义成员变量,又可以定义成员函数,还有访问级别。
C++语言设计目的之一就是为了更好地兼容C语言,那么C++中,struct关键字也应该继续兼容C语言中的使用和表达的含义。于是C++中便引入了新的关键字:class代替struct用于类的定义
注:C++中原来的struct用于定义类的这种使用方法仍然适用。class和struct的使用方法基本完全相同。
但是class和struct在默认访问级别时是不同的:
class A
{
public: //公有成员
在类的外部可以访问
private: //私有成员
类的外部是不可访问的,只有类内部和友元函数可以访问私有成员
protected: //受保护成员
保护成员在派生类(即子类)中是可访问的
};
- 类域访问内部成员变量或成员函数:类名::变量/函数
注:"::"是作用域访问符号
类的声明和实现
(1)声明—Operator.h头文件:满足用户的实际需求
#ifndef _OPERATOR_H_//防止重复头文件声明
#define _OPERATOR_H_
class Operator//定义了一个Operator类
{
private:
char mOp;
double mP1;
double mP2;
public:
bool setOperator(char op);//设置运算的类型:+ - * /
void setParameter(double p1, double p2);//设置运算参数
bool result(double& r);//运算结果返回
};
#endif
(2)实现—Operator.cpp:需求的实际实现过程
#include "Operator.h"//自己定义的头文件要用双引号" "
bool Operator::setOperator(char op)//参数用于接收运算符'+' '-' '*' '/' 字符
{
bool ret = false;
if( (op == '+') || (op == '-') || (op == '*') || (op == '/') )
{
ret = true;
mOp = op;
}
else
{
mOp = '\0';
}
return ret;
}
void Operator::setParameter(double p1, double p2)//传入的参数:左操作数和右操作数
{
mP1 = p1;
mP2 = p2;
}
bool Operator::result(double& r)//将实际运算结果的返回保存r中;返回结果:表示运算是否成功
{
bool ret = true;
switch( mOp )//运算符匹配
{
case '/':
if( (-0.000000001 < mP2) && (mP2 < 0.000000001) )
{
ret = false;
}
else
{
r = mP1 / mP2;
}
break;
case '+':
r = mP1 + mP2;
break;
case '*':
r = mP1 * mP2;
break;
case '-':
r = mP1 - mP2;
break;
default:
ret = false;//运算失败
break;
}
return ret;//运算成功
}
(3)使用—main.cpp:功能的使用
#include <stdio.h>
#include "Operator.h"
int main()
{
Operator op;//定义了一个对象op
double r = 0;//变量r用于保存运算的结果
op.setOperator('/');//设置运算方式
op.setParameter(9, 3);//传参
if( op.result(r) )
{
printf("r = %lf\n", r);
}
else
{
printf("Calculate error!\n");
}
return 0;
}