物以类聚,人以群分,在生活中,我们习惯将事物进行分类,在程序设计中也是可以引入分类的思想。
中国的12生肖可以将人分成不同的类型;
外国的12星座也是将人分成不同的类型;
按照财富的多少分高产、中产、低产,也是将人进行分类;
官员的九品等级也是将官员进行分类;
老虎也分为东北虎、华南虎,孟加拉虎等;
将日常生活中的思维习惯引入到程序设计中;
将需求中的概念直观的映射到解决方案中;
以模块为中心构建可复用的软件系统;
提高软件产品的可维护性和可扩展性;
类:指的是一类事物,是一个抽象的概念,比如高产、中产、低产;
对象:指的是某个类的具体实体,比如笔者就是低产这类人中的一个对象;
一个类又可以分成多个小类,比如人类是一个类,人类可以分成黄种人、白种人、黑种人等小类,黄种人还可以继续分类,如中国人、韩国人、日本人等。
把事物分类就是为了方便区分,分类一般是按照属性和行为来分的。
继承
从已存在的类中细分出来的类与原类之间具有继承关系;
继承的类,也叫做子类,拥有原类,也叫做父类的所有属性和行为;
如东北虎是从老虎这个类中细分出来的,东北虎具有老虎的所有属性和行为;
组合
一些类的存在依赖于其他的类,这种关系叫组合;
组合的类在某个局部行由其他的类组成;
比如电脑这个类,是由内存、主板、显示器、硬盘等东哥类组成的;
生物类(可细分成动物类和植物类)
生物类的属:有生命
动物类(继承于生物类类)
动物类的属性:有生命,可移动
动物类的行为:找事物
植物类(继承于生物类类)
植物类的属性:有生命,可生长
人类(继承于动物类)
人类的属性:有生命,可移动
人类的行为:找食物、睡觉、劳动
禽兽类(继承于动物类)
禽兽类的属性:有生命、可移动
禽兽类的行为:找食物、睡觉
类:生物{
属性:有生命
}
类:动物继承生物{
属性:可移动
行为:找食物
}
类:植物继承生物{
属性:可生长
}
类:禽兽继承动物{
行为:睡觉
}
类:人类继承动物{
行为:睡觉
行为:劳动
}
struct 生物{
属性:有生命
}
struct 动物:生物{
属性:可移动
行为:找食物
}
struct 植物:生物{
属性:可生长
}
struct 禽兽:动物{
行为:睡觉
}
struct 人类:动物{
行为:睡觉
行为:劳动
}
struct Biology
{
bool living;
};
struct Animal :Biology
{
bool movable;
void findFood()
{
printf("I need food!\n");
}
};
struct Plant :Biology
{
bool growable;
};
struct Beast :Animal
{
void sleep()
{
printf("I need sleep!\n");
}
};
struct Human :Animal
{
void sleep()
{
printf("I need sleep!\n");
}
void work()
{
printf("I need work!\n");
}
};
当实用类的时候,不需要关心类的使用细节;
只有在创建类的时候,才需要考虑内部的实现细节;
所谓封装就是将类的实现细节封起来。
1、成员变量:用于表示类属性的变量
2、成员函数:用于表示类行为的函数
3、成员变量和成员函数的访问级别
public:成员变量和成员函数可以在类的内部和外界访问;
private:成员变量和成员函数只能在类的内部被访问;
比如:
一个女生的外貌就是公开的,自己和别人都看得到,这就是public;
但是女生的年龄别人是看不见的,只有自己知道,这就是private;
要想知道这个女生的年龄,那就得让这个女生自己告诉你才行。
程序实例1:公有属性(public)和私有属性(private)的访问
#include
struct Biology
{
bool living;
};
struct Animal :Biology
{
bool movable;
void findFood()
{
printf("I need food!\n");
}
};
struct Plant :Biology
{
bool growable;
};
struct Beast :Animal
{
void sleep()
{
printf("I need sleep!\n");
}
};
struct Human :Animal
{
void sleep()
{
printf("I need sleep!\n");
}
void work()
{
printf("I need work!\n");
}
};
struct Girl :Human
{
private: //私有属性
int age;
int weight;
public://公有属性
void print()
{
age = 22;
weight = 48;
printf("I'm %d years old.\n",age);
printf("My weight is %d.\n", weight);
}
};
struct Boy :Human
{
private://私有属性
int height;
int salary;
public://公有属性
int age;
int weight;
void print()
{
height = 175;
salary = 10000;
printf("My height is %d.\n", height);
printf("My salary is %d.\n", salary);
}
};
int main()
{
Girl g;//创建一个对象g,跟定义一个变量差不多
Boy b;//创建一个对象b
//g.age = 20; //不能直接给g.age赋值,因为女孩的年龄是私有变量,不对外公开
g.print();//可以通过询问女孩,让女孩自己告诉你
b.age = 30; //可以给b.age赋值,因为男生的年龄是公有变量
b.print();//询问男孩的身高和收入
return 0;
}
输出结果:
I'm 22 years old.
My weight is 48.
My height is 175.
My salary is 10000.
类成员(包括成员变量和成员函数)的作用域都是在类的内部,外部无法直接访问;
类的成员函数可以直接访问成员变量和调用成员函数;
类的外部可以通过类变量(也就是对象)来访问public成员;
类成员的作用域与访问级别没有关系;
C++中用struct 定义的类,如果没有定义私有还是公有的属性,那么默认就是公有属性(public);
程序实例2:类成员作用域
#include
int i = 1; //定义一个全局变量i
struct Test
{
private:
int i; //在类里面定义一个私有变量i
public:
int j;//在类里面定义一个公有变量j
int getI()
{
i = 3;
return i;
}
};
int main()
{
int i = 2; //定义一个局部变量i
Test test;
test.j = 4;
printf("i = %d\n", i);//打印局部变量i
printf("::i = %d\n", ::i); //打印全局变量i
//printf("test.i = %d\n",test.i); //类对象不能访问私有变量i
printf("test.j = %d\n", test.j); //类对象可以访问公有变量j
printf("test.getI() = %d\n", test.getI());//通过类成员函数访问类的私有变量
return 0;
}
输出结果:
i = 2
::i = 1
test.j = 4
test.getI() = 3
struct在C语言中是表示结构体的,但是经过不断地改进已经越来越不像结构体了,既然已经变味了那就变得彻底一点吧。C++中有个新的关键字class,专门用来定义类。
其实class关键字和struct关键字的用法基本是一样的,只有一点小差异:
在用struct定义类时,所有成员的默认访问级别是public;
在用class定义类时,所有成员的默认访问级别是private;
struct A
{
int i; //默认是public
int getI() //默认是public
{
return i;
}
};
class B
{
int i; //默认是private
int getI() //默认是private
{
return i;
}
};
程序实例3:struct定义类与class定义类对比
#include
struct A
{
int i; //默认是public
int getI() //默认是public
{
return i;
}
};
class B
{
int i; //默认是private
int getI() //默认是private
{
return i;
}
};
int main()
{
A a;
B b;
a.i = 4;//struct定义的类默认的是公有变量,可以直接访问
printf("a.getI() = %d\n",a.getI());
//b.i = 5;//class定义的类默认的是私有变量,不能直接访问
//printf("b.getI() = %d\n", b.getI());
return 0;
}
提供setOperatior函数设置运算类型;
提供setParameter函数设置运算参数;
提供result函数进行运算:返回值表示运算的合法性,通过引用参数返回结果。
C++的类支持声明和实现分开操作,将类的实现和定义分开:
.h头文件中只有类的声明,包括成员变量和成员函数的声明;
.cpp源文件中完成类中成员函数的具体实现;
头文件Operator.h
#pragma once
class Operator
{
private:
char mOp;
double mP1;
double mP2;
public:
bool setOperator(char op);
void setParameter(double p1, double p2);
bool result(double& r);
};
源文件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)
{
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;
}
main函数中使用类
#include
#include "Operator.h"
int main()
{
Operator op;
double r = 0;
op.setOperator('/');
op.setParameter(5,3);
if (op.result(r))
{
printf("r = %lf\n", r);
}
else
{
printf("calculate error\n");
}
return 0;
}