C++:【练习题】类的继承与多态性

习题1

1.1 题目:

请编写程序完成如下设计

  • 学生类,数据成员包括学号(公有)、姓名(保护)、年龄(私有)、学生数(静态)。学生数用来统计构造出来的学生对象数量
  • 课代表类,继承自学生类,数据包括负责课程编号(公有)、课程评分(公有)
  • 要求使用构造初始化符表“:”的形式进行构造,每个类又相关数据的输出显示函数
  • 在主函数中构造对象并输出显示相关数据

1.2 解题思路:

  • 构建学生类,创建各类数据成员
  • 创建课代表类继承学生类
  • 初始化静态成员变量
  • 构造对象进行调试

1.3 代码及注释:

#include<iostream>
using namespace std;


//定义学生类
class Student {
public:
	Student(char* n, int i, int a) {
		char *p = new char[strlen(n) + 1];
		name = p;
		strcpy_s(name, strlen(n) + 1, n);
		total_num++;
		id = i;
		age = a;
	}
	//获取各个成员变量
	static int GetTotal() { return total_num; }
	char* GetName() { return name; }
	int GetAge() { return age; }
	int GetId() { return id; }
	//显示学生信息
	void Display() {
		cout << "Name: " << name << endl;
		cout << "Id  : " << id << endl;
		cout << "Age : " << age << endl << endl;
	}
	int id;
protected:
	char *name;
private:
	static int total_num;
	int age;
};

//初始化静态成员变量
int Student::total_num = 0;


//定义课代表类
class Lesson_rep :public Student {
public:
	Lesson_rep(char* n, int i, int a, int l, double s) :Student(n, i, a) {
		lesson_num = l;
		score = s;
	}
	int lesson_num;
	double score;
	//显示课代表信息
	void Display() {
		cout << "Name: " << GetName() << endl;
		cout << "Id  : " << GetId() << endl;
		cout << "Age : " << GetAge() << endl;
		cout << "Lesson Number: " << lesson_num << endl;
		cout << "Lesson Score : " << score << endl << endl;
	}
};

int main() {
	Student stu1("Mike", 112268, 19);
	Student stu2("Eve", 113980, 18);
	Student stu3("Michael", 127923, 17);
	Lesson_rep stu4("Jack", 118888, 20, 666666, 87.62);
	cout << "Information about Michael:" << endl;
	stu3.Display();
	
	cout << "Information about Jack:" << endl;
	stu4.Display();

	cout << "Total Number of Students: " << Student::GetTotal() << endl;

}

1.4 程序运行结果分析:

我们创建4个学生,并展示普通学生Michael的信息和课代表Jack的信息,结果如下:

Information about Michael:
Name: Michael
Id  : 127923
Age : 17

Information about Jack:
Name: Jack
Id  : 118888
Age : 20
Lesson Number: 666666
Lesson Score : 87.62

Total Number of Students: 4
请按任意键继续. . .

验证可得程序执行正确。

习题2

2.1 题目:

  • 定义一个点Point类,数据成员是浮点型横纵坐标;
  • 定义一个颜色类Color数据成员只有颜色(字符数组#000000~#FFFFFF);
  • 一个直线类Line,数据成员是两个Point对象,表示起点和终点(即Point两个对象为Line的内嵌对象);
  • 一个三角形类Triangle,继承自Line和Color,数据成员有三角形的高height,三角形理解成以基类Color为颜色,以基类直线为底,以height为高的直角三角形,(即直线和高分别为两条直角边)请实现相关函数,计算三角形的颜色、周长和面积并给出相关输出

2.2 解题思路:

  • 定义点类及其数据成员
  • 定义颜色类及其数据成员
  • 定义直线类,其包含两个点类对象作为数据成员
  • 定义三角形类,继承直线类和颜色类并构造相关的数据成员和成员函数
  • 在主函数内构建三角形对象,进行调试测验

2.3 代码及注释:

#include<iostream>
#include<cstring>
using namespace std;


//定义Point类
class Point {
public:
	Point() { x = y = 0; }
	Point(float a, float b) { x = a, y = b; }
	//获取参数x和y
	float GetX() { return x; }
	float GetY() { return y; }
private:
	float x;
	float y;
};



//定义Color类
class Color {
public:
	Color() { strcpy_s(color, 8, "#000000"); }
	Color(char *c) { strcpy_s(color, 8, c); }
	//获取颜色参数color
	char* GetColor() { return color; }
private:
	char color[8];
};


//定义Line类
class Line {
public:
	Line() :start(0, 0), end(0, 0) {}
	Line(float x1, float y1, float x2, float y2) :start(x1, y1), end(x2, y2) {}
	Point* GetStart() { return &start; }
	Point* GetEnd() { return &end; }
	//获取线段长度
	float GetLength() { return sqrt(pow(start.GetX() - end.GetX(), 2) + pow(start.GetY() - end.GetY(), 2)); }
private:
	Point start, end;
};



//定义Triangle类
class Triangle :public Line, public Color {
public:
	Triangle() :Line(), Color() { height = 0; }
	Triangle(char* c, float h, float x1, float y1, float x2, float y2) :Line(x1, y1, x2, y2), Color(c) { height = h; }
	//获取面积
	float GetArea() { return height * GetLength() * 0.5; }
	//获取周长
	float GetPerimeter() { return height + GetLength() + sqrt(pow(height, 2) + pow(GetLength(), 2)); }
	//显示基本信息
	void Display() {
		cout << "   Color      :  " << GetColor() << endl;
		cout << "   Area       :  " << GetArea() << endl;
		cout << "   Perimeter  :  " << GetPerimeter() << endl << endl;
	}
private:
	float height;
};


int main() {
	Triangle test("#CCCCCC", 4, 2, 5, 2, 8);
	cout << "Basic Information about Triangle test :" << endl;
	test.Display();
	return 1;
}

2.4 程序运行结果分析:

结果如下:

Basic Information about Triangle a :
     Color   : #CCCCCC
     Area    : 6
   Perimeter : 12

请按任意键继续. . .

输出结果均符合检验,因此,程序执行正确。

习题3

3.1 题目:

设计日期类和时间类,并以此两类为基类派生日期时间类

要求:

  • 日期类包括年、月、日等成员

  • 时间类包括时、分、秒等成员

  • 日期时间类能够实现日期时间的求差、比较大小的功能

    1、使用运算符重载实现该功能,以时间日期类的对象描述日期时间之差

    2、假设每个月都是30天,不考虑闰年

    3、不考虑公元前

3.2 解题思路:

  • 定义日期类及其数据成员

  • 定义时间类及其数据成员

  • 定义日期时间类继承日期类和时间类

  • 对日期时间类进行关系运算符(==,>,>=,<,<=)重载

  • 对日期时间类进行双目运算符(-)重载

  • 因为时间不能为负数,故定义减法运算为:

    任意两数相减,其结果为大数减去小时,结果为二者时间差

  • 在主函数内调试程序

3.3 代码及注释:

#include<iostream>
using namespace std;

// 定义日期类
class Date {
public:
	friend class DateTime;
	Date() {
		year = 2000;
		month = 1;
		day = 1;
	}
	Date(int year_, int month_, int day_) {
		year = year_;
		month = month_;
		day = day_;
	}
private:
	int year;
	int month;
	int day;
};

// 定义时间类
class Time {
public:
	friend class DateTime;
	Time() {
		hour = 0;
		minute = 0;
		second = 0;
	}
	Time(int hour_, int minute_, int second_) {
		hour = hour_;
		minute = minute_;
		second = second_;
	}
private:
	int hour;
	int minute;
	int second;
};


// 定义日期时间类,继承日期类和时间类
class DateTime :public Date, public Time {
public:
	DateTime() :Date(), Time() {}
	DateTime(int year_, int month_, int day_, int hour_, int minute_, int second_)
		:Date(year_, month_, day_), Time(hour_, minute_, second_) {}
	void Check() {
		if (month < 0) {
			year--;
			month += 12;
		}
		if (day < 0) {
			month--;
			day += 30;
		}
		if (hour < 0) {
			day--;
			hour += 24;
		}
		if (minute < 0) {
			hour--;
			minute += 60;
		}
		if (second < 0) {
			minute--;
			second += 60;
		}
	}

	//显示日期时间
	void Display() {
		cout << year << '-' << month << '-' << day << ' ' << hour << ':' << minute << ':' << second << endl;
	}

	// 关系运算符重载
	bool operator ==(const DateTime &dt) {
		if (year == dt.year && month == dt.month && day == dt.day
			&& hour == dt.hour && minute == dt.minute && second == dt.second)
			return true;
		else
			return false;
	}
	bool operator >(const DateTime &dt) {
		if (year > dt.year)return true;
		else if (year < dt.year)return false;
		else if (month > dt.month)return true;
		else if (month < dt.month)return false;
		else if (day > dt.day)return true;
		else if (day < dt.day)return false;
		else if (hour > dt.hour)return true;
		else if (hour < dt.hour)return false;
		else if (minute > dt.minute)return true;
		else if (minute < dt.minute)return false;
		else if (second > dt.second)return true;
		else if (second < dt.second)return false;
		else return false;
	}
	bool operator >=(const DateTime &dt) {
		if (year > dt.year)return true;
		else if (year < dt.year)return false;
		else if (month > dt.month)return true;
		else if (month < dt.month)return false;
		else if (day > dt.day)return true;
		else if (day < dt.day)return false;
		else if (hour > dt.hour)return true;
		else if (hour < dt.hour)return false;
		else if (minute > dt.minute)return true;
		else if (minute < dt.minute)return false;
		else if (second > dt.second)return true;
		else if (second < dt.second)return false;
		else return true;
	}
	bool operator <(const DateTime &dt) {
		if (year < dt.year)return true;
		else if (year > dt.year)return false;
		else if (month < dt.month)return true;
		else if (month > dt.month)return false;
		else if (day < dt.day)return true;
		else if (day > dt.day)return false;
		else if (hour < dt.hour)return true;
		else if (hour > dt.hour)return false;
		else if (minute < dt.minute)return true;
		else if (minute > dt.minute)return false;
		else if (second < dt.second)return true;
		else if (second > dt.second)return false;
		else return false;
	}
	bool operator <=(const DateTime &dt) {
		if (year < dt.year)return true;
		else if (year > dt.year)return false;
		else if (month < dt.month)return true;
		else if (month > dt.month)return false;
		else if (day < dt.day)return true;
		else if (day > dt.day)return false;
		else if (hour < dt.hour)return true;
		else if (hour > dt.hour)return false;
		else if (minute < dt.minute)return true;
		else if (minute > dt.minute)return false;
		else if (second < dt.second)return true;
		else if (second > dt.second)return false;
		else return true;
	}

	// 双目运算符重载
	// 因为时间不存在负数,故任意两者的差值是为大数减去小数,即绝对值
	DateTime operator -(const DateTime &dt) {
		const DateTime *front, *rear;
		if (*this > dt) {
			front = this;
			rear = &dt;
		}
		else {
			front = &dt;
			rear = this;
		}
		DateTime c;
		c.year = front->year - rear->year;
		c.month = front->month - rear->month;
		c.day = front->day - rear->day;
		c.hour = front->hour - rear->hour;
		c.minute = front->minute - rear->minute;
		c.second = front->second - rear->second;
		c.Check();
		return c;
	}

};


int main() {
	// 定义两个测试的DataTime对象进行测试
	DateTime dt1(2000, 7, 4, 16, 45, 50);
	DateTime dt2(2000, 8, 4, 22, 15, 40);
	cout << "dt1 = ";
	dt1.Display();
	cout << "dt2 = ";
	dt2.Display();

	cout << "dt1 == dt2 :";
	if (dt1 == dt2)
		cout << "true" << endl;
	else
		cout << "false" << endl;

	cout << "dt1 >= dt2 :";
	if (dt1 >= dt2)
		cout << "true" << endl;
	else
		cout << "false" << endl;

	cout << "dt1 <= dt2 :";
	if (dt1 <= dt2)
		cout << "true" << endl;
	else
		cout << "false" << endl;

	cout << "dt1 > dt2  :" ;
	if (dt1 >dt2)
		cout << "true" << endl;
	else
		cout << "false" << endl;

	cout << "dt1 < dt2  :" ;
	if (dt1 < dt2)
		cout << "true" << endl;
	else
		cout << "false" << endl;


	DateTime dt3;
	dt3 = dt2 - dt1;
	cout << "dt2 - dt1  :";
	dt3.Display();
	return 0;
}

3.4 程序运行结果分析:

调试结果如下:

dt1 = 2000-7-4 16:45:50
dt2 = 2000-8-4 22:15:40
dt1 == dt2 :false
dt1 >= dt2 :false
dt1 <= dt2 :true
dt1 > dt2  :false
dt1 < dt2  :true
dt2 - dt1  :0-1-0 5:29:50
请按任意键继续. . .

验证可得程序执行正确。

习题4

4.1 题目:

设计圆类,并以圆类为基类,派生圆柱类、圆锥类和圆球类(分别求出其面积和体积)

要求:

  • 自行确定各类具有的数据成员、函数成员,如果需要对象成员,再自行设计相关类;
  • 在设计程序过程中,尽量多地涉及类继承与多态性的重要概念,如虚函数、纯虚函数、抽象基类等等。

4.2 解题思路:

  • 构建抽象基类Area和Volume并编写纯虚函数GetArea和GetVolume
  • 定义圆类继承抽象基类Area,重写虚函数GetArea
  • 定义圆柱类继承圆类和抽象基类Volume,重写虚函数GetArea和GetVolume
  • 定义圆锥类继承圆类和抽象基类Volume,重写虚函数GetArea和GetVolume
  • 定义圆球类继承圆类和抽象基类Volume,重写虚函数GetArea和GetVolume
  • 在主函数内进行调试

4.3 代码及注释:

#include<iostream>
using namespace std;

// 定义数学常数pi
#define pi 3.1415926

// 创建抽象基类Area
class Area {
public:
	virtual double GetArea() = 0;
};

// 创建抽象基类Volume
class Volume {
public:
	virtual double GetVolume() = 0;
};

// 创建基类Circle圆类
class Circle:public Area {
public:
	friend class Cylinder;
	friend class Cone;
	friend class Sphere;
	Circle() {}
	Circle(double r_) { r = r_; }
	virtual double GetArea() { return pi*r*r; }
private:
	double r;
};

// 创建圆柱类
class Cylinder :public Circle, public Volume {
public:
	Cylinder() :Circle() {}
	Cylinder(double r_, double h_) :Circle(r_) { h = h_; }
	virtual double GetArea() { return 2 * pi*r*r + 2 * pi*r*h; }
	virtual double GetVolume() { return pi*r*r*h; }
private:
	double h;
};

// 创建圆锥类
class Cone :public Circle, public Volume {
public:
	Cone() :Circle() {}
	Cone(double r_, double h_) :Circle(r_) { h = h_; }
	virtual double GetArea() { return pi*r*r + 2 * pi*r*sqrt(h*h + r*r) / 2; }
	virtual double GetVolume() { return pi*r*r*h / 3; }
private:
	double h;
};

// 创建球类
class Sphere :public Circle, public Volume {
public:
	Sphere() :Circle() {}
	Sphere(double r_) :Circle(r_) {}
	virtual double GetArea() { return 4 * pi*r*r; }
	virtual double GetVolume() { return 4 * pi*r*r*r / 3; }
};

int main() {
	Circle circle(2);
	cout << "创建一个圆对象" << endl;
	cout << "半径 :2.0" << endl;
	cout << "面积 :" << circle.GetArea() << endl << endl;

	Cylinder cylinder(2, 3);
	cout << "创建一个圆柱对象" << endl;
	cout << "半径 :2.0" << endl;
	cout << "高度 :3.0" << endl;
	cout << "面积 :" << cylinder.GetArea() << endl;
	cout << "体积 :" << cylinder.GetVolume() << endl << endl;

	Cone cone(2, 3);
	cout << "创建一个圆锥对象" << endl;
	cout << "半径 :2.0" << endl;
	cout << "高度 :3.0" << endl;
	cout << "面积 :" << cone.GetArea() << endl;
	cout << "体积 :" << cone.GetVolume() << endl << endl;

	Sphere sphere(2);
	cout << "创建一个球对象" << endl;
	cout << "半径 :2.0" << endl;
	cout << "面积 :" << sphere.GetArea() << endl;
	cout << "体积 :" << sphere.GetVolume() << endl << endl;
	return 0;
}

4.4 程序运行结果分析:

创建对象进行测试,结果如下:

创建一个圆对象
半径 :2.0
面积 :12.5664

创建一个圆柱对象
半径 :2.0
高度 :3.0
面积 :62.8319
体积 :37.6991

创建一个圆锥对象
半径 :2.0
高度 :3.0
面积 :35.2207
体积 :12.5664

创建一个球对象
半径 :2.0
面积 :50.2655
体积 :33.5103

请按任意键继续. . .

根据验算得结果均无误,因此,程序执行正确。

  • 15
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是Java代码设计一个学生Student及使用SomeStudents创建对象和调用方法的示例: ```java public class Student { private int no; private String name; private float grade; private static float sum; private static int num; public Student(int n, String na, float d) { no = n; name = na; grade = d; sum += d; num++; } public float average() { return sum / num; } public void display() { System.out.println("学号:" + no + ",姓名:" + name + ",成绩:" + grade); } } public class SomeStudents { public static void main(String[] args) { Student s1 = new Student(1, "张三", 90.5f); Student s2 = new Student(2, "李四", 88.0f); Student s3 = new Student(3, "王五", 95.5f); System.out.println("平均分:" + s1.average()); s1.display(); s2.display(); s3.display(); } } ``` 这段代码中,我们定义了一个Student和一个SomeStudents。首先在Student中定义了所需的成员变量和方法,其中构造方法用于初始化成员变量,并实现累加总分和人数的功能。average方法返回平均分,display方法输出学生的基本信息。 在SomeStudents中,我们创建3个Student对象,并使用这些对象调用上面定义的方法。运行程序,输出结果如下: ``` 平均分:91.333336 学号:1,姓名:张三,成绩:90.5 学号:2,姓名:李四,成绩:88.0 学号:3,姓名:王五,成绩:95.5 ``` 以上就是我们使用Java编程设计学生并创建对象调用方法的示例,希望能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值