第一篇:人工智能教案04章 4.7 面向对象的表示法
4.7 面向对象的表示法
人工智能的语言有Lisp(函数型)、Prolog(逻辑型)和SmallTalk(面向对象型)。SmallTalk是基于对知识的面向对象表示的。
1960年,人工智能研究的先驱者之一,美国的McCarthy推出了他设计的语言LISP。LISP是LISt Processor(表处理器)的意思。它之前的计算机高级语言如Fortran主要用于数值计算,而LISP则主要用于符号计算,它的主要数据结构是表。LISP至今仍在广泛使用,很大部分的人工智能程序是用LISP写的,她为人工智能的发展作出了不可磨灭的贡献。
Prolog(PROgramming in LOGic)采用的是用逻辑方法作程序设计的思想,它把一阶谓词演算中的说明性命题赋予过程性的解释,从而使说明性的命题变成可执行的过程。
SMALLTALK是面向对象的程序设计语言中的主要代表。它由Alan Kay设计出来。整个系统包含四个组成部分:语言核心,编程风范,编程系统和界面模型。SmallTalk程序以面向对象为基础,对象组织成类,凡是能被计算机处理的数据都可以定义为对象。类构成继承的层次体系,每个类可以包含一些方法,这些方法可以被子类继承也可以不被继承,类之间的操作通过传递消息实现。
对象是由一组数据和与该组数据相关的操作构成的实体。在面向对象表示中类和类继承是一组重要概念。类由一组变量和一组操作组成,它描述了一组具有相同属性和操作的对象。每一个对象都属于某一类,每个对象都可由相关的类生成,换言之,对象是类的实例。一个类可以通过继承拥有另一类的全部变量和操作,继承是面向对象表示法的主要推理形式。同时,由于一个事物的描述都集中在一个类中,又体现了类的封装性。继承和封装是面向对象的两大特点。
第二篇:人工智能教案04章 4.2 表示观
4.2 表示观
任何科学研究都是有其指导思想、观点的,在一定的思想指导下提出一系列的方法体系。知识表示也是同样。人工智能是处理知识的科学,所以对人工智能研究首先从知识表示开始,而指导知识表示的思想观点称为表示观。
不同的表示观规定了智能模拟研究的不同侧面。各种表示观是从不同角度及不同描述层次解释表示的内涵时产生的不同的结论。
表示观:对于“什么是表示”这一基本问题的不同理解和采用的方法论。4.2.1 认识论表示观
认识论表示观认为表示是对自然世界的表述,表示自身不显示任何智能行为。其唯一的作用就是携带知识。这意味着表示可以独立于启发式来研究。
认识论表示观的思想最早出现于J.McCarthy与P.Hayes的一篇文章中。此主张的核心是将AI问题分成两部分:认识论部分与启发式部分。认为AI的核心任务就是“常识”形式化。其讨论的主要问题:
◇“知识的不完全性”是认识论学派讨论最多的情况。推理者的知识是不完全,但却是一致的,其要点是在保持知识一致性的前提下得出新的结论。
例如对知识“鸟会飞”,但是“鸵鸟”并不会飞。
◇“知识不一致性”是常识的另一类性质。
例如教友派教徒是和平主义者,共和党是好战分子。已知某教授是教友派教徒,且是共和党人。问他是和平主义者吗?
◇“知识不确定性”是更复杂的常识问题。尽管Fuzzy、可信度理论、人工神经网络等丰富了对常识的不确定性研究方法。但还不能显现地表示“可废弃性”这个重要特征。大大限制了对智能型为“灵活性”的描述。因此,在复杂问题求解释,集成几种方法是有吸引力的想法。
◇“常识的相对性”目前在AI中研究甚少。理论集合是有限的,常识的集合是无限的。
关于常识的研究非常困难。这种困难性首先在于常识知识难以形式化,因为常识知识实在是太多了。Doug Lenat在考虑建立一个人类级智能系统所需要的知识的数量时,他认为大约需要100万到1000万个事实。其次,没有很好的定义使我们能控制独立于其他部分的边界。在概念化一个常识时,可能牵涉到太多的实体、功能和关系,使得我们无法确定什么时候它已经“概念化”好了。
认识论的特点:
◇ 表示是在特定环境下对世界观察的结果;
◇ 强调自然世界现象与表示之间的因果关系;
◇ 认为启发式方法不属于表示研究的内容,认为对常识知识的形式化是非常重要的任务。4.2.2 本体论表示观
本体论表示观认为表示是对自然世界的一种近似,它规定了看待自然世界的方式。即一个约定的集合。表示只是描述了关心的一部分,逼真是不可能的。
该观点是由D.Lenta提出的。该观点认为表示主要解决的问题是:
◇ 表示需对世界的某个部分给与特别的注意(聚集),而对世界的另外部分衰减,以求达到有效求解。
◇ 对世界可以采用不同的方式来记述。注重的不是“其语言形式,而是其内容”。此内容不是某些特定领域的特殊的专家知识,而是自然世界中那些具有普通意义的一般知识。
◇ 推理是表示观中不可缺少的一部分。表示研究应与启发式搜索联系起来。认为不考虑推理的纯粹表示是不存在的。
◇ 计算效率无疑是表示的核心问题之一。即有效地知识组织及与领域有关的启发式知识是其提高计算效率的手段。
计算效率:不同于以前的多用计算复杂性来衡量一种智能系统的方法,而采用计算困难度来衡量。
一般情况下,计算复杂性是实例的算法在极端情况下的衡量的特性。实例是人造的,分布往往不平衡,而且,实例问题是能解决的。但是,实际问题往往不能解决。计算困难度主要讨论:计算复杂性的分布与研究困难有多大的问题。如对大多数有价值的实例遇到难以克服的计算复杂性问题,就研究如何克服。
◇ 哪种语言作为表示形式不是最重要的。特别强调表示不是数据。
本体论的特点:
◇ 本体论的约定具有相对性。本体论研究者认为在智能系统中,往往需要分成不同的层次。每个层次具有其本体论的约定。这对专家系统一类的问题已被证明是有效的。
如电子线路分析。对电子线路的分析,如果从“电路是相互连接的实体,信号顺着联线瞬时地流动”这个观点,则存在着一种本体论。而如果从电动力学来看,则存在另一种本体论。
◇ 如要建立一个具有普通意义的带有一般知识的知识库,将会遇到“相对性”的困难。因为,如果站在不同的科学深度将导致不同的本体论约定。那么,什么是其最终的本体论约定哪?这是本体论表示观至今未能解决的问题。
Minsky的说明是有代表性的。“在解释非常复杂的问题时,我们将不得不同时使用几个完全不同的表示。这是因为,每一种特别的表示均有其自身的优点与缺陷。对涉及我们称为常识的那些东西时,没有一种表示可以说是足够的。”采用集成的方法来克服理论不足所带来的困难,不仅对“本体论”表示观是必然的。而且对其它两种表示观也是必然的。4.2.3 知识工程表示观
最常用的表示法都反映了知识工程表示观。其特点是:
◇ 将表示理解为一类数据结构(逻辑)及在其上的操作。
◇ 对知识的内容更强调与领域的相关性,适合于这个领域的,来自领域专家经验知识是讨论的重点。
这种观点最大的特色就是强调工程实现性,表示方法必须在实际的应用中得到实现。同时,这种观点所强调的知识领域有关性和对知识表示形式的选择性与本体论有着显著的差别。
一般地说,认识论表示观强调知识的某种存在性研究,本体论表示观更多地考虑知识的构造性研究,而知识工程表示观则以知识系统的可实现性作为重点。显然,对任意一门科学存在性、构造性及可实现性均是重要的,简单地论断某种表示观是否合适是错误的。
注意:无论持何种表示观的AI研究者都认为,表示是刻画智能行为的理论。这表示无论采用什么样的方式(包括数学的或程序的)所建立的表示方法和立足于什么样的表示观,均需要满足与智能现象一致的条件。鉴于智能现象的复杂性,采用什么表示观,应当取决于所面临的问题。笼统地强调好的是没有什么意义的。近几年一些研究者主张各种表示观应该互相渗透。
第三篇:java面向对象程序设计教案
武汉大学珞珈学院 系/教研室 Java 面 向 对 象 程 序 设 计 课 教 案
主讲教师:熊春秀 编写时间:2011-4-30
第一章:概述
第 1、2 节:面向对象的基本概念、面向对象程序设计概述 授课时间:2011-2-
22、23
计划学时数:1 教学任务与目的:让学生理解面向对象的基本概念 教学重点:掌握面向对象的基本概念 教学难点:理解面向对象程序设计的方法 教学方法:多媒体+板书 参考书目:《面向对象程序设计导论》,[美]C.Thomas wu著,电子工业出版社 专业词汇:Java虚拟机、Applet程序 备注
第二章:Java特点及运行环境
第 1、2、3 节:Java语言特点、Java应用程序及运行环境、Java Applet程序及运行环境 授课时间:2011-2-
22、23
计划学时数:3 教学任务与目的:让学生学会JDK的下载、安装与环境配置。教学重点:掌握编译和执行Java程序的基本步骤
教学难点:理解Java程序的入口并能够通过命令行传递参数 教学方法:多媒体+板书 参考书目:《面向对象程序设计导论》,[美]C.Thomas wu著,电子工业出版社 专业词汇:JDK、lib、bin 备注 第三章:Java语言基础
第 1、2 节:Java程序的构成、数据类型、表达式以及流程控制语句 授课时间:2011-3-
1、2
计划学时数:3 教学任务与目的:让学生学会Java基本的数据类型和表示方法、数值类型的运算、逻辑运算和比较、条件执行语句(包括三种条件语句和switch语句)、循环控制语句(包括for、while、do while循环及相应的辅助语句)、字符串类String和BufferString以及数组的声明及使用。
教学重点:掌握Java基本的数据类型和表示方法
教学难点:理解Java程序的循环控制语句(包括for、while、do while循环及相应的辅助语句)
教学方法:多媒体+板书 参考书目:《Java语言与面向对象程序设计》,印旻编著,清华大学出版社 专业词汇:变量、数据类型、循环控制语句 备注 第三章:Java语言基础 第 3 节:Java与C比较
授课时间:2011-3-
8、9
计划学时数:3 教学任务与目的:让学生在C语言的基本上进一步学习Java语言。教学重点:掌握Java语言与C语言的区别与联系。教学难点:理解Java语言在C语言上的改进。教学方法:多媒体+板书 参考书目:《Java2参考大全(第四版)》,[美]Herbert Schildt著,张玉清、吴浦峰、尚勇等译,清华大学出版社。专业词汇:Java、C 备注 第四章:抽象、封装与类
第 1 节:抽象、封装与Java类的概念
授课时间:2011-3-
15、16
计划学时数:3 教学任务与目的:让学生学会面向对象的基本特征、掌握如何定义一个类以及如何生成对象、深入掌握方法的定义及技巧、深入掌握类的访问权限与封装机制、深入掌握包的定义与包的使用方法。
教学重点:掌握类的定义与对象的生成。教学难点:理解类的抽象与封装机制。教学方法:多媒体+板书 参考书目:《Java2 实用教程》,耿祥义、张跃平编著,清华大学出版社。专业词汇:抽象、封装、类 备注 第四章:抽象、封装与类 第 2 节:系统定义的类
授课时间:2011-3-
22、23
计划学时数:3 教学任务与目的:让学生学会使用系统定义的类,并掌握与用户自定义类的区别。教学重点:掌握如何定义所需要的类。
教学难点:熟悉Java平台定义了哪些经常要用到、而且满足我们需要的类。教学方法:多媒体+板书 参考书目:《Java2 实用教程》,耿祥义、张跃平编著,清华大学出版社。专业词汇:系统定义的类、用户自定义类 备注 第四章:抽象、封装与类
第 3 节:类、域和方法的修饰符
授课时间:2011-3-
29、30
计划学时数:3 教学任务与目的:让学生学会类的声明。
教学重点:掌握如何定义类的修饰和方法的修饰符。教学难点:熟悉类的变量的定义与使用方法。教学方法:多媒体+板书 参考书目:《Java2 实用教程》,耿祥义、张跃平编著,清华大学出版社。专业词汇:成员变量、类变量、成员方法、类方法 备注 第五章:继承与多态
第 1、2 节:Java的继承与派生、域的继承与隐藏 授课时间:2011-4-
5、6
计划学时数:3 教学任务与目的:让学生全面掌握面向对象的基本特征、掌握如何使用继承性来到达软件的重用、深入掌握继承过程中域的隐藏和方法的覆盖技巧。教学重点:掌握如何使用继承性来到达软件的重用。教学难点:熟悉继承过程中域的隐藏和方法的覆盖技巧。教学方法:多媒体+板书 参考书目:《Java2 实用教程》,耿祥义、张跃平编著,清华大学出版社。专业词汇:继承派生、域、隐藏 备注 第五章:继承与多态
第 3、4 节:方法的继承、重载与覆盖、this与super、构造函数的继承与重载 授课时间:2011-4-
12、13
计划学时数:3 教学任务与目的:让学生通过继承可以更有效地组织程序结构,明确类之间的关系,并充分利用已有的类来创建新类,通过继承可以实现代码的重用,以完成更复杂的设计、开发。教学重点:掌握类的重载与覆盖的区别与联系。教学难点:熟悉类的重载与覆盖使用方法。教学方法:多媒体+板书 参考书目:《Java语言与面向对象程序设计》,印旻编著,清华大学出版社。专业词汇:继承、重载、覆盖、this、super 备注 第五章:继承与多态
第 5、6 节:多态性的实现、接口声明与实现 授课时间:2011-4-
19、20
计划学时数:3 教学任务与目的:让学生深入掌握抽象类和抽象方法的定义,掌握多态通过统一多个相关类的对外接口,在运行时根据不同的情况执行不同的操作,提高类的抽象度和灵活性,深入掌握接口的定义和使用技巧。
教学重点:熟悉多态性实现的两种方式以及接口的实现。教学难点:熟悉多态性与接口的实现方法。教学方法:多媒体+板书 参考书目:《Java语言与面向对象程序设计》,印旻编著,清华大学出版社。专业词汇:多态性、接口 备注 第六章:工具类与算法
第 1、2 节:语言基础类库、Applet类与小程序的基本原理 授课时间:2011-4-
26、27
计划学时数:3 教学任务与目的:深入了解Applet生命周期的主要方法和特点、熟练掌握Applet程序的编写方法、深入了解Applet的安全机制及其合理运用。教学重点:熟练掌握Applet程序的编写方法。
教学难点:深入了解Applet的安全机制及其合理运用。教学方法:多媒体+板书 参考书目:《Java语言与面向对象程序设计》,印旻编著,清华大学出版社。专业词汇:Applet、生命周期 备注 第六章:工具类与算法
第 3、4 节:数组、字符串、常用算法
授课时间:2011-5-
3、4
计划学时数:3 教学任务与目的:让学生学会字符串类String和BufferString、数组的声明及使用。教学重点:熟练掌握字符串与数组的使用方法。教学难点:深入了解数组的使用方法。教学方法:多媒体+板书 参考书目:《Java语言与面向对象程序设计》,印旻编著,清华大学出版社。专业词汇:数组、字符串 备注 第七章:用户图形界面的设计
第 1、2 节:用户自定义成分、事件驱动设计 授课时间:2011-5-
10、11
计划学时数:3 教学任务与目的:让学生学会使用面向对象的程序设计方法构建图形用户界面、深入了解抽象窗口工具包(AWT)、掌握事件处理基本原理和方法。教学重点:熟练掌握图形用户界面的开发方法。教学难点:深入了解图形界面的各种事件。教学方法:多媒体+板书 参考书目:《Java语言与面向对象程序设计》,印旻编著,清华大学出版社。专业词汇:AWT、GUI 备注 第七章:用户图形界面的设计
第 3、4 节:GUI对象,包括:按钮、文本框、鼠标、键盘等事件的处理、布局设计 授课时间:2011-5-
17、18
计划学时数:3 教学任务与目的:让学生深入了解GUI构件及掌握布局控制方法、熟练掌握菜单和对话框、掌握简单绘图方法。
教学重点:熟练使用Java语言提供的布局管理器来管理组件在容器中的布局。教学难点:深入了解组件在程序中安排中位置和大小使用方法。教学方法:多媒体+板书 参考书目:《Java语言与面向对象程序设计》,印旻编著,清华大学出版社。专业词汇:布局管理器、容器 备注 第八章:Java高级编程
第 1、2、3节:异常处理、多线程机制、Java程序对网上资源的访问 授课时间:2011-5-
24、25
计划学时数:3 教学任务与目的:让学生深入理解多线程的基本概念、熟练掌握创建线程的两种基本方法、熟练处理线程的同步问题和死锁问题、深入理解异常的基本概念、熟悉和掌握Java平台定义异常类、熟练掌握创建自定义异常类的方法。教学重点:熟练掌握创建线程的两种基本方法。教学难点:深入了解线程的同步问题和死锁问题。教学方法:多媒体+板书 参考书目:《Java语言与面向对象程序设计》,印旻编著,清华大学出版社。专业词汇:同步、死锁、多线程、异常
第四篇:《C++面向对象程序设计》教案
《面向对象程序设计》课程教案
课程编号:08051230
课程名称:面向对象程序设计(Object-oriented Programming)学时:72学时,其中理论学时54,上机学时18 学分:3.5开课部门:数学与计算机科学学院 开课教研室:计算机科学 开课教师:雷小园 开课学期:第7学期
授课班级:04信计
先修课程:C语言程序设计
考核要求:考试,平时10%,实验20%,考试70% 使用教材:
《C++面向对象程序设计教程(第2版)》,陈维兴,清华大学出版社,2004年 《C++面向对象程序设计习题解答与实验指导》,陈维兴,清华大学出版社,2004年
教学目的与要求:
《面向对象程序设计》是一门计算机及相关专业的重要的专业基础课。本课程讲述C++语言面向对象的基本特性,包括类、对象、派生类、继承、运算符重载、多态性、虚函数、函数模板、类模板、输入输出、流类库、文件等,使学生掌握面向对象程序设计的基本概念和基本方法,能运用C++语言进行基本的面向对象程序设计。
教学方法:
采用板书讲解C++程序设计,再加以上机练习C++编程。
3章 类和对象
3.1 类与对象的基本概念
3.2 构造函数与析构函数
例:点类 Point class Point { private: int x,y;public: Point(){};Point(int xx, int yy){ x=xx;y=yy;} Point(Point &p){ x=p.x;y=p.y;} int GetX()const { return x;} int GetY()const { return y;} void SetXY(int xx, int yy){ x=xx;y=yy;} void Show();};void Point::Show(){ cout<<“X: ”< 例:人类 Person class Person { protected: char *name;int age;char sex;public: Person(char *n, int a, char s);Person(){ name = 0;age = 0;sex = ' ';} Person(Person &p);~Person(){ delete[] name;} void SetName(char *n);void SetAge(int a){ age = a;} void SetSex(int s){ sex = s;} char *GetName()const { return name;} int GetAge()const { return age;} char GetSex()const { return sex;} void Show();}; #include “person.h” #include Person::Person(char *n, int a, char s){ name = new char[strlen(n)+1];strcpy(name,n);age = a;sex = s;} Person::Person(Person &p){ name = new char[strlen(p.name)+1];strcpy(name,p.name);age = p.age;sex = p.sex;} void Person::SetName(char *n){ delete[] name;name = new char[strlen(n)+1];strcpy(name,n);} void Person::Show(){ cout<<“Name: ”< 1、对象数组 所谓对象数组是指每一数组元素都是对象的数组。 2、对象指针 声明对象指针的一般语法形式为:类名* 对象指针名。当用指向对象的指针来访问对象成员时,要用“->”操作符。 3、this指针 C++为成员函数提供了一个名字为this的指针,这个指针称为自引用指针。每当通过一个对象调用一个成员函数时,系统就自动把这个this指针指向该对象。因此使用的数据成员就是该对象的数据成员。 3.4 向函数传递对象 1、使用对象作为函数参数 2、使用对象指针作为函数参数 3、使用对象引用作为函数参数 3.5 静态成员 1、静态数据成员 在一个类中,若将一个数据成员说明为static,这种成员称为静态数据成员。与一般的数据成员不同,无论建立多少个类的对象,都只有一个静态数据的拷贝。从而实现了同一个类的不同对象之间的数据共享。 定义静态数据成员的格式如下: static 数据类型 数据成员名;静态数据成员在该类定义之外被初始化。访问静态数据成员可以通过对象或指针来访问,也可以通过类名::来访问。 2、静态成员函数 定义静态成员函数的格式如下: static 返回类型 静态成员函数名(参数表);与静态数据成员类似,调用公有静态成员函数的一般格式有如下几种: 类名::静态成员函数名(实参表)对象.静态成员函数名(实参表)对象指针->静态成员函数名(实参表) 例:点类 Point(演示静态成员)class Point { private: int x,y;static int count;public: Point(int xx=0, int yy=0){ x=xx;y=yy;count++;} Point(Point &p){ x=p.x;y=p.y;count++;} int GetX()const { return x;} int GetY()const { return y;} void SetXY(int xx, int yy){ x=xx;y=yy;} static int GetCount(){ return count;} }; int Point::count=0; int main(){ Point a(100,200), b;cout< 1、友元函数 友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访问该类的所有对象的成员,包括私有成员、保护成员和公有成员。 2、友元成员 一个类的成员函数也可以作为另一个类的友元,这种成员函数不仅可以访问自己所在类对象中的所有成员,还可以访问friend声明语句所在类对象中的所有成员。 3、友元类 一个类也可以作为另一个类的友元。 友元关系是单向的,不具有交换性。若类X是类Y的友元,类Y不一定是类X的友元。友元关系也不具有传递性。若类X是类Y的友元,Y是类Z的友元,类X不一定是类Z的友元。 例:点类 Point(演示友元)class Point { private: int x,y;static int count;public: Point(int xx=0, int yy=0){ x=xx;y=yy;} int GetX()const { return x;} int GetY()const { return y;} void SetXY(int xx, int yy){ x=xx;y=yy;} friend double Dist(Point p1, Point p2);}; friend double Dist(Point p1, Point p2);{ double x,y;x=p1.x-p2.x;y=p1.y-p2.y;return sqrt(x*x+y*y);} int main(){ Point a(100,200), b(300,400);cout<<“两点间的距离为:”< 例:圆类 Circle(包含Point类的写法)class Circle { private: double radius;//半径 Point center;//圆心 public: Circle(){} Circle(int x, int y, double r): center(x,y){ SetRadius(r);} Circle(Point p, double r): center(p){ SetRadius(r);} double GetRadius()const { return radius;} void SetRadius(double r){ radius =(r>=0 ? r : 0);} void SetValue(int x, int y, double r){ center.SetXY(x,y);SetRadius(r);} double Area();void Show();}; const double PI=3.14159;inline double Circle::Area(){ return PI * radius * radius;} void Circle::Show(){ cout<<“圆心为: ” center.Show();cout<<“半径为: ”< 1、const引用 const引用的说明形式如下: const 类型说明符& 引用名 2、const对象 const对象的说明形式如下: const 类名 对象名[(参数表)];如:const Data Mybirthday(1980,1,1);const对象的数据成员值不能被改变,const对象必须进行初始化。通过const对象只能调用它的const成员函数,而不能调用普通成员函数。 3、const数据成员 const数据成员只能通过构造函数的初始化列表来获得初始值。 4、const成员函数 const成员函数的说明格式如下: 类型说明符 函数名(参数表)const;如:int GetYear()const { return year;} const成员函数不能更新对象的数据成员,也不能调用对象的普通成员函数。const是函数类型的一个组成部分,因此在函数的实现部分也要带关键字const。 5、引用类型的数据成员 引用类型的数据成员也只能通过构造函数的初始化列表来进行初始化。 例 class Test { private: int a;const int b;//不能写成const int b=10,因类的定义还没分配空间 int &c;//不能写成const int &c=a,因变量a还没分配空间 public: Test(int i,int j,int &k):b(j),c(k){ a=i;} Test():b(10),c(a){ a=20;} } 第4章 派生类与继承 4.1 派生类的概念 4.2 派生类的构造函数与析构函数 例:圆类 Circle(继承Point类的写法)class Circle: public Point { private: double radius;//半径 public: Circle(){} Circle(int x, int y, double r): Point(x,y){ SetRadius(r);} Circle(Point p, double r): Point(p){ SetRadius(r);} double GetRadius()const { return radius;} void SetRadius(double r){ radius =(r>=0 ? r : 0);} void SetValue(int x, int y, double r){ SetXY(x,y);SetRadius(r);} double Area();void Show();}; const double PI=3.14159;inline double Circle::Area(){ return PI * radius * radius;} void Circle::Show(){ cout<<“圆心为: ” Point::Show();cout<<“半径为: ”< 1、派生类继承了它的所有基类中除构造函数和析构函数之外的所有成员。 2、在派生类中成员按访问属性划分为四种:不可访问的成员、私有成员、保护成员、公有成员。 3、对从基类继承下来的成员初始化工作是通过调用基类的构造函数来完成的,调用方法是在派生类的构造函数中用初始化列表。 4、如果在派生类的构造函数省略了基类的初始化列表,则将调用基类的缺省构造函数。 5、如果基类定义了带有参数的构造函数时,派生类就应当定义构造函数,以便显式地调用基类的构造函数。 6、如果派生类定义了与基类同名的新数据成员或成员函数,则此派生类的成员就覆盖了基类的同名成员,直接使用成员名只能访问到派生类的成员。 7、在同名覆盖的情况下,可以使用基类名+作用域分辨符来访问基类的同名成员。 8、如果派生类和基类的某个成员函数重名,但参数表不同,仍然属于覆盖,不属于重载。 9、对派生类的对象,构造函数的执行过程是:先调用基类的构造函数(按它们被继承时声明的顺序),再调用内嵌对象成员的构造函数(按内嵌对象声明的顺序),最后执行自己的构造函数体中的内容。 10、析构函数的调用次序正好和构造函数的调用次序相反。 例:学生类 Student //student.h #include “person.h” class Student: public Person { protected: char *Department;int Number;public: Student(){ Department = 0;Number = 0;} Student(char *, int, char, char *, int);Student(Student &stu);~Student(){ delete[] Department;} void SetDep(char*);void SetNum(int num){ Number = num;} char *GetDep()const { return Department;} int GetNum()const { return Number;} void Show();}; //student.cpp #include “student.h” #include Student::Student(char *name,int age,char sex,char *dep,int num): Person(name, age, sex){ Department = new char[strlen(dep)+1];strcpy(Department, dep);Number = num;} Student::Student(Student &stu): Person(stu){ Department = new char[strlen(stu.Department)+1];strcpy(Department, stu.Department);Number = stu.Number;} void Student::SetDep(char *dep){ delete[] Department;Department = new char[strlen(dep)+1];strcpy(Department, dep);} void Student::Show(){ Person::Show();cout<<“Department: ” < 4.4 多重继承 例1:X和Y是基类,Z从X和Y派生 class X { public: int b;X(int k){ b=k;} };class Y { public: int c;Y(int k){ c=k;} };class Z: public X, public Y { public: int d;Z(int i,int j,int k):X(i),Y(j){ d=k;} } 例2:X和Y都从W派生而来 class W { public: int a;W(int k){ d=k;} };class X: public W { public: int b;X(int i, int k): W(i){ b=k;} };class Y: public W { public: int c;Y(int i, int k): W(i){ c=k;} };class Z: public X, public Y { public: int d;Z(int i, int j, int k, int l): X(i,j),Y(i,k){ d=l;} } int main(){ Z t(10,20,30,40);cout< 例3:将W做为X和Y的虚基类 class W { public: int a;W(int k){ a=k;} };class X: virtual public W { public: int b;X(int i, int k): W(i){ b=k;} };class Y: virtual public W { public: int c;Y(int i, int k): W(i){ c=k;} };class Z: public X, public Y { public: int d;Z(int i, int j, int k, int l): W(i),X(i,j),Y(i,k){ d=l;} } int main(){ Z t(10,20,30,40);cout< (2)建立一个对象时,如果这个对象中含有从虚基类继承来的成员,则虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。该派生类的其他基类对虚基类构造函数的调用都自动被忽略。 (3)若同一层次中同时包含虚基类和非虚基类,应先调用虚基类的构造函数,再调用非虚基类的构造函数,最后调用派生类构造函数;(4)对于多个虚基类,构造函数的执行顺序仍然是先左后右,自上而下;(5)对于非虚基类,构造函数的执行顺序仍是先左后右,自上而下;(6)若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数。 4.5 赋值兼容规则 所谓赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。 附:线性表——顺序表 class SeqList { private: int *data;int size;int MaxSize;public: SeqList(int sz=100);~SeqList(){ delete []data;} int Length()const { return size;} bool IsEmpty()const { return size==0;} void Insert(const int &x, int k);void Delete(int k);int GetData(int k)const;int Find(const int &x)const;void Show()const;};SeqList::SeqList(int sz){ MaxSize=sz;data=new int[MaxSize];size=0;} void SeqList::Insert(const int &x, int k){ if(k<1 || k>size+1){ cerr<<“越界出错”;exit(1);} if(size==MaxSize){ cerr<<“顺序表已满”;exit(1);} for(int i=size-1;i>=k-1;i--)data[i+1]=data[i];data[k-1]=x;size++;} void SeqList::Delete(int k){ if(size==0){ cerr<<“顺序表空”;exit(1);} if(k<1 || k>size){ cerr<<“越界出错”;exit(1);} for(int i=k;i int SeqList::GetData(int k)const { if(k<1 || k>size){ cerr<<“越界出错”;exit(1);} return data[k-1];} int SeqList::Find(const int &x)const { for(int i=0;i void SeqList::Show()const { for(int i=0;i 第5章 多态性 5.1 编译时的多态性与运行时的多态性 5.2 函数重载 5.3 运算符重载 例:复数类Complex //mycomplex.h #include #include“mycomplex.h” #include Complex &Complex::operator+=(Complex &c){ re += c.re;im += c.im;return *this;} Complex &Complex::operator-=(Complex &c){ re-= c.re;im-= c.im;return *this;} Complex &Complex::operator*=(Complex &c){ double t = re * c.rere * c.im)/ m;re = t;return *this;} Complex operator+(Complex &a, Complex &b){ return Complex(a.re + b.re, a.im + b.im);} Complex operator-(Complex &a, Complex &b){ return Complex(a.reb.im);} Complex operator*(Complex &a, Complex &b){ return Complex(a.re * b.rea.re * b.im)/ m);} bool operator==(Complex &a, Complex &b){ return a.re == b.re && a.im == b.im;} bool operator!=(Complex &a, Complex &b){ return a.re!= b.re || a.im!= b.im;} ostream &operator<<(ostream &os, Complex &c){ os << c.re << '+' << c.im << 'i';return os;} istream &operator>>(istream &is, Complex &c){ is >> c.re >> c.im;return is;} 例:分数类 Fraction #include class Fraction { private: int num, den;void reduce();public: Fraction(int n=0, int d=1);Fraction operator+(){ return *this;} Fraction operator-(){ return Fraction(-num, den);} Fraction &operator+=(Fraction &);Fraction &operator-=(Fraction &);Fraction &operator*=(Fraction &);Fraction &operator/=(Fraction &);Fraction &operator++();Fraction operator++(int);operator double();friend Fraction operator+(Fraction &, Fraction &);friend Fraction operator-(Fraction &, Fraction &);friend Fraction operator*(Fraction &, Fraction &);friend Fraction operator/(Fraction &, Fraction &);friend bool operator==(Fraction &, Fraction &);friend bool operator!=(Fraction &, Fraction &);friend bool operator<(Fraction &, Fraction &);friend bool operator<=(Fraction &, Fraction &);friend bool operator>(Fraction &, Fraction &);friend bool operator>=(Fraction &, Fraction &);friend ostream &operator<<(ostream &, Fraction &);friend istream &operator>>(istream &, Fraction &);};#include “fraction.h” #include 5.4 类型转换 1、通过构造函数将别的类型转换为这个类的类型 如复数Complex类的构造函数 Complex(double r){ re=r;} 2、通过转换函数讲这个类的类型转换为别的类型 如在复数Complex类中的转换函数 operator double(){ return re;} 在分数Fraction类中的转换函数 operator double(){ return static_cast 用explicit关键字,可以禁止单个参数的构造函数用于自动类型转换,如 class Stack { explicit Stack(int size);„ „ } Explicit也同样禁止用赋值来进行带有类型转换的初始化行为 如,不可以 Stack s=10;5.5 虚函数 1、引入派生类后的对象指针 例: class A { public: void show(){ cout<<“A”;} };class B:public A { public: void show(){ cout<<“B”;} };int main(){ A a,*pc;B b;pc=&a;pc->show();pc=&b;pc->show();} 输出为AA 2、虚函数的定义及使用 例:引入虚函数后,上面的例子改为如下 class A { public: virtual void show(){ cout<<“A”;} };class B:public A { public: void show(){ cout<<“B”;} };int main(){ A a,*pc;B b;pc=&a;pc->show();pc=&b;pc->show();} 输出为AB 3、纯虚函数和抽象类 例: class A { public: virtual void show()=0;};class B:public A { public: void show(){ cout<<“B”;} };int main(){ A *pc;B b;pc=&b;pc->show();} 关于虚函数,有以下几点 1、如果成员函数是通过引用或指针,而不是通过对象来调用,那么,如果没有使用virtual,程序将根据引用类型或指针类型来选择方法;如果使用了virtual,程序将根据引用或指针指向的对象的类型来选择方法。 2、如果要在派生类中重新定义基类的方法,则将它设置为虚拟方法,否则是指为非虚拟方法 3、如果使用指向对象的引用或指针来调用虚拟方法,程序将使用为对象类型定义的方法,而不使用为引用类型或指针类型定义的方法,这称为动态联编或晚期联编。 4、在基类方法的声明中使用virtual可使该方法在基类以及所有的派生类中都是虚拟的。 5、一个未在派生类中定义的纯虚函数仍旧还是一个纯虚函数,该派生类仍为一个抽象类。 6、通常应给基类提供一个虚拟析构函数,这样,当派生类对象结束时,将先调用派生的析构函数,再调用基类的析构函数。 7、如果派生类没有重新定义虚拟函数,则将使用该函数的基类版本。 8、如果重新定义继承的方法,应确保与原来的原型完全相同。但有一个例外,就是如果返回类型是基类指针或引用,则可改为指向派生类的指针或引用。实验 基本C++程序设计 2 类和对象程序设计 3 派生与继承程序设计 4 运算符重载程序设计 5 模板程序设计 6 I/ O 流程序设计 【课题】 1.2集合的表示法(教案) 【教学目标】 使学生掌握常使用的集合的表示方法,能选择自然语言、图形语言、集合语言(列举法和描述法)描述不同的具体问题;【教学重点】 集合的表示方法; 【教学难点】 集合的特征性质的概念,以及运用特征性质描述法表示集合。【课时安排】 【教学过程 】 一、复习引入 问题一: 集合、空集、有限集和无限集分别是怎样定义的?集合元素与集合的关系是什么?集合的元素具有哪些特征?常用数集的记法是什么? 问题二: 集合的表示方法有哪些?分别适用于什么情况? 学生阅读课本,先独立思考,再互相讨论,教师巡视。 二、讲授新课 集合常用的表示方法 1.列举法定义:如果一个集合是有限集,元素又不太多,常常把集合的所有元素都列举出来,写在花括号“{ }”内表示这个集合,这种表示集合的方法叫做列举法 如:(1)24的所有正因数构成的集合。可表示为{1,2,3,4,6,8,12,24}(2)不大于100的自然数的全体构成的集合。可表示为{0,1,2,„100} 说明:使用列举法时应注意: 使用情况: 集合是有限集元素又不太多 集合是有限集,元素较多,有一定的规律,可列出几个元素作为代表,其他元素用省略号表示。 有规律的有限集 (2)用列举法表示集合时,不必考虑元素的前后顺序,要注意不重不漏。 2、描述法定义: 描述法的定义﹕常用于表示无限集合,把集合中元素的公共属性用文字﹐符号或式子等描述出来﹐写在大括号内﹐这种表示集合的方法叫做描述法:如果在集合I中,属于集合{xI|p(x)}A的任意一个元素x都具有性质p(x),而不属于集合A的元素都不具有性质p(x),则性质p(x)叫做集合A的一个特征性质。于是,集合A可以用它的特征性质p(x)描述为 举例:由不等式x-3>2的所有解组成的集合(即不等式x-3>2的解集),可表示为:{xRx-32} 例:用特征性质描述法表示法表示下列集合:(1){-1,1}; (2)大于3的全体正偶数构成的集合; 思考与讨论: 哪些性质可作为集合{xN0x5}的特征性质? (2)平行四边形的哪些性质,可用来描述所有平行四边形构成的集合? 使用特征性质描述法是注意: 1.特征性质必须明确,可多种表示; 2.当x在R中取值时,常常省略不写 ; 3.有的集合也可以直接写出元素名称,并并用花括号括起来表示这列元素的全体。 三、举例说明 例:2用列举法表示下列集合 1 A={xN0 2 B={xx2-5x+6=0}. 四、课堂练习教科书第7练习第1题,第2题 五、归纳小结 1、列举法、描述法的定义及适用范围 2、注意事项 3、列举法与描述法的相互转化 六、布置作业:教材第7页习题二第1题,第二题第五篇:集合的表示法(教案)