{key}面向对象程序设计-C++ polymorphism 【第十三次上课笔记】

Peronal Link: http://segmentfault.com/a/1190000002464822

这节课讲了本门课程 面向对象程序设计中最为重要的一个部分 - 多态

 1 /*************************************************************************
 2     > File Name: polymorphism.cpp
 3     > Author: Jeremy Wu
 4     > Created Time: Mon 25 May 2015 10:04:07 AM CST
 5     > Function: tune every instrument
 6  ************************************************************************/
 7
 8 //多态:一个接口,多种实现
 9 //发生多态现象的条件:
10 //    1.通过调用虚函数(基类中必须要有,派生类中可有可无建议加上)
11 //    2.借助指针或者引用调用该虚函数
12 //
13 //虚函数只能是 非静态 成员函数
14 //如果类中有虚函数,最好把 析构函数 也定义为虚函数
15 //
16 //如果基类的析构函数是虚函数,由它派生的所有的派生类的析构函数都 自动 成为虚函数
17 // ·构造函数无法定义为虚函数
18 //
19 //基类可以指向它的所有的派生类
20 //相当于基类给所有的派生类提供了统一的接口
21 //一般不会直接创建基类的对象
22 //
23 //{ 抽象基类 }
24 //如果一个类中包含纯虚函数,就是抽象类
25 //抽象类无法创建对象
26 //如果需要 避免 创建基类对象,应该使用纯虚函数
27
28
29
30 //接下来是一个例子,有一个基类叫做乐器类
31 //由它派生出Wind , Brass 和 Gitar 三个类
32
33 #include <iostream>
34
35 using namespace std;
36
37 class Instrument {
38 public:
39     virtual void play ();    //virtual 关键字
40     Instrument () { cout << "Instement () " << endl; }
41     virtual ~Instrument () { cout << "~Instement () " << endl; }
42 };
43
44 void Instrument::play () {    //类的外部定义前不用加 virtual 关键字
45     cout << "Instrument::play ()" << endl;
46 }
47
48 class Wind : public Instrument{
49     virtual void play () { cout << "Wind::play () " << endl; }    //派生类中 virtual 关键字可加可不加
50     ~Wind () { cout << "Wind::~Wind ()" << endl; }
51 };
52
53 class Brass : public Instrument {
54     virtual void play () { cout << "Brass::play ()" << endl; }
55     ~Brass () { cout << "Brass::~Brass () " << endl; }
56 };
57
58 class Gitar : public Instrument {
59     virtual void play () { cout << "Gitar::play ()" << endl; }
60     ~Gitar () { cout << "Gitar::~Gitar ()" << endl; }
61 };
62
63 //inst 指针在定义的时候,是静态类型
64 //在程序运行过程中,它的动态类型就会根据指向对象的类型作改变
65 //
66 //有时候把动态绑定称为运行时绑定,也称后继绑定
67 //run-time binding
68
69 void tune (Instrument * inst) {    //引用传递 或者用指针
70     inst->play ();                //Dynamic binding
71                                 //在编译时进行 动态绑定
72 }
73
74 int main () {
75
76     Instrument * p = new Gitar;
77     Instrument * p2 = new Wind;
78
79     delete p;
80     delete p2;
81
82     return 0;
83 }


接下来老师出了一道题目

描述如下:

以下是我的 Solution:

 1 /*************************************************************************
 2     > File Name: ployPROB.cpp
 3     > Author: Jeremy Wu
 4     > Created Time: Mon 25 May 2015 10:50:07 AM CST
 5  ************************************************************************/
 6
 7 //定义一个形状类的继承结构
 8 //
 9 //Shape -> Triangle
10 //        -> Rectangle
11 //        -> Circle
12 //
13 //给形状定义两个操作:
14 //    getArea () 求面积
15 //    getLength () 求周长
16
17 #include <iostream>
18 #include <cmath>
19
20 const double PI = 3.1415926;
21
22 using namespace std;
23
24 class Shape {
25 public:
26     virtual double getArea () = 0;
27     virtual double getLength () = 0;
28     virtual ~Shape () { cout << "~Shape ()" << endl; }
29     Shape () { cout << "Shape ()" << endl; }
30 };
31
32 class Triangle : public Shape {
33 private:
34     double x, y, z;
35 public:
36     double getArea () {
37         double p = (x + y + z) / 2.0;
38         return sqrt (p * (p - x) * (p - y) * (p - z));
39     }
40     double getLength () { return x + y + z; }
41     Triangle (double ix = 0.0, double iy = 0.0, double iz = 0.0) {
42         x = ix, y = iy, z = iz;
43     }
44     ~Triangle () { cout << "~Triangle () " << endl; }
45 };
46
47 class Rectangle : public Shape {
48 private:
49     double x, y;
50 public:
51     double getArea () { return x * y; }
52     double getLength () { return 2.0 * (x + y); }
53     Rectangle (double ix = 0.0, double iy = 0.0) {
54         x = ix, y = iy;
55     }
56     ~Rectangle () { cout << "~Rectangle () " << endl; }
57 };
58
59 class Circle : public Shape {
60 private:
61     double r;
62 public:
63     double getArea () { return PI * r * r; }
64     double getLength () { return 2.0 * PI * r; }
65     Circle (double ir = 0.0) {
66         r = ir;
67     }
68     ~Circle () { cout << "~Circle ()" << endl; }
69 };
70
71 void test (Shape & sp) {
72     cout << "/***********************************/" << endl;
73     cout << ‘\t‘ << "Area is " << sp.getArea () << endl;
74     cout << ‘\t‘ << "Length is " << sp.getLength () << endl;
75     cout << "/***********************************/" << endl;
76 }
77
78 int main () {
79
80     Circle p1 (3.0);
81     Rectangle p2 (3.0, 6.0);
82     Triangle p3 (1.0, 2.0, 1.5);
83
84     test (p1);
85     test (p2);
86     test (p3);
87
88     return 0;
89 }


以下是官方版 Solution:

 1 /*************************************************************************
 2     > File Name: example.cpp
 3     > Author: Jeremy Wu
 4     > Created Time: Mon 25 May 2015 11:34:47 AM CST
 5  ************************************************************************/
 6
 7 #include <iostream>
 8 #include <cmath>
 9
10 using namespace std;
11
12 class Shape {
13 public:
14     virtual double area () = 0;    //不实现基类可以这么写,表示定义一个纯虚函数
15     virtual double zhou () = 0; //pure virtual function
16 };
17
18 class Triangle : public Shape {
19     double a, b, c;
20 public:
21     Triangle (double aa, double bb, double cc) : a (aa), b (bb), c (cc) {}
22     virtual double area () {
23         double p = 0.5 * (a + b + c);
24         return sqrt (p * (p - a) * (p - b) * (p - c));
25     }
26     virtual double zhou () {
27         return a + b + c;
28     }
29 };
30
31 class Rectangle : public Shape {
32     double a, b;
33 public:
34     Rectangle (double aa, double bb) : a (aa), b (bb) {}
35     virtual double area () {
36         return a * b;
37     }
38     virtual double zhou () {
39         return 2.0 * (a + b);
40     }
41 };
42
43 class Circle : public Shape {
44     double r;
45 public:
46     Circle (double rr) : r (rr) {}
47     virtual double area () {
48         return 3.14159 * r * r;
49     }
50     virtual double zhou () {
51         return 2.0 * 3.14159 * r;
52     }
53 };
54
55 void printArea (Shape * p) {
56     cout << p->area () << endl;
57 }
58
59 void printZhou (Shape * p) {
60     cout << p->zhou () << endl;
61 }
62
63 int main () {
64
65     Shape * p1, * p2, * p3;
66
67     //Shape sp;
68
69     p1 = new Triangle (6, 7, 8);
70     p2 = new Rectangle (10, 4.6);
71     p3 = new Circle (5.8);
72
73     printArea (p1);
74     printArea (p2);
75     printArea (p3);
76
77     printZhou (p1);
78     printZhou (p2);
79     printZhou (p3);
80
81     return 0;
82 }
时间: 2024-10-07 13:22:57

{key}面向对象程序设计-C++ polymorphism 【第十三次上课笔记】的相关文章

面向对象程序设计-C++ Inheritance &amp; Multiple inheritance &amp; RTTI【第十三次上课笔记】

Sadly, 这节课带过去的笔记本没电了 T^T 导致没有一行 Code, Sorry 笔记如下: 1 Shape * p1; //使用指针创建对象的方法 2 p = new Circle (2.0); 3 Shape * p2; 4 p = new Rectangle (3.0, 5.0); 5 6 class Shape { 7 public: 8 virtual double area () = 0; //Pure virtual function 9 } 10 11 //Warning:

面向对象程序设计-C++ Stream &amp; Template &amp; Exception【第十五次上课笔记】

这是本门<面向对象程序设计>课最后一次上课,刚好上完了这本<Thinking in C++> :) 这节课首先讲了流 Stream 的概念 平时我们主要用的是(1)在屏幕上输入输出的 cin cout 流 (2)在文件中输入输出的 ifstream ofstream 流 (3)在字符串中输入输出的 istringstream ostringstream istrstream ostrstream 流 具体实例可以看以下代码: /***************************

Python基础(16)_面向对象程序设计(类、继承、派生、组合、接口)

一.面向过程程序设计与面向对象程序设计 面向过程的程序设计:核心是过程,过程就解决问题的步骤,基于该思想设计程序就像是在设计一条流水线,是一种机械式的思维方式 优点:复杂的问题的简单化,流程化 缺点:扩展性差 面向对象的程序设计:核心是对象,对象是特征(变量)与技能(函数)的结合体,是一种上帝式的思维方式 优点:解决了程序的扩展性 缺点:可控性差 二.类和对象 以游戏举例,基于面向对象设计一个款游戏:英雄联盟,每个玩家选一个英雄,每个英雄都有自己的特征和和技能,特征即数据属性,技能即方法属性,特

复习 深入理解Java面向对象程序设计1

复习 深入理解Java面向对象程序设计 类是一种抽象的概念,对象是类的一种具体表示形式,是具体的概念.先有类,然后由类生成对象(Object).对象又叫做实例(Instance). 类由两大部分构成:属性及方法.属性一般用名词来表示,方法一般用动词来表示. 如果一个Java源文件定义了多个类,那么这些类中最多只有一个类是public的,换句话说,定义的多个类可以都不是public的. 在Java中进行方法的参数传递时,无论传递的是原生数据类型还是引用类型,参数传递方式统一是传值(pass by

[.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能

[.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能 本节导读: 上节说了缓存是以空间来换取时间的技术,介绍了客户端缓存和两种常用服务器缓布,本节主要介绍一种.NET中特别重要的缓布技术Cache.利用Cache提升程序性能. 1. 缓存Cache的命名空间 .NET中对缓存有两个命名空间 命名空间1:System.Web.Caching 命名空间2:System.Runtime.Caching 引用范围:这两个命名空间,都可以在Web和非WEB应用程序中

CH15 面向对象程序设计

面向对象程序设计是基于三个基本概念的:数据抽象.继承和多态. 第7章介绍了数据抽象的知识,简单来说,C++通过定义自己的数据类型来实现数据抽象. 数据抽象是一种依赖于接口和实现分离的编程技术:类的设计者必须关心类是如何实现的,但使用该类的程序员不必了解这些细节. 封装是一项将低层次的元素组合起来形成新的.高层次实体的技术!函数和类都是封装的具体形式.其中类代表若干成员的聚集.大多数(设计良好的)类类型隐藏了实现该类型的成员. 一个简单的PersonInfo类,包含类成员.成员函数.构造函数 1

面向对象程序设计-C++ Finial exam review NOTES【第十六次上课笔记】

写在前面: 我记得也不全,如果有记录的更全的同学可以留言,我会添加哒 :) 常量 内敛函数 为什么需要内敛函数 内敛函数适用于什么场合 内敛函数本身,最大优点是,避免了真正函数调用的开销 因为普通函数调用会有开销,比如开辟一个栈,结束了还要释放局部变量 如果函数体只有寥寥几行,是不值得使用函数 在函数体代码比较短小的时候,使用频繁的,应该使用内敛函数 最大优点:没有函数调用开销,又解决了带有参数宏的简单替换,它有类型检查 引用 什么是引用:给这块区域的数据再增加一个名称(本质含义) 表面上看,相

Java面向对象程序设计--与C++对比说明:系列3(Java 继承机制)

继承(inheritance)背后的核心思想是:可以在现有类的基础上创建自己的新类,在新类中继承原来类的方法和数据域,并添加适合当前应用场景的新的数据和方法. 1. 类,超类,子类 (class,superclass,subclass): Java 中的inheritance都是public inheritance,并不想C++中存在public,protected和private inheritance的分类. class subclass extends superclass; 这里有两个要

2017-2018-2 20165318 实验三《Java面向对象程序设计》实验报告

2017-2018-2 20165318 实验三<Java面向对象程序设计>实验报告 一.实验报告封面 课程:Java程序设计        班级:1653班        姓名:孙晓暄        学号:20165318 指导教师:娄嘉鹏                              实验日期:2018年4月27日 实验时间:13:45 - 3:25                    实验序号:实验三 实验名称:敏捷开发与XP实践 实验内容: XP基础 XP核心实践 相关工