第九章 类的继承与多态性
- 格式:ppt
- 大小:198.00 KB
- 文档页数:33


第一章物流信息系统概论1。
1.1物流信息:含义:物流活动中各环节生成的信息,一般是随着生产、消费的物流活动而产生的,与物流过程中的运输、储存、装卸、包装等各种职能有机结合在一起,是整个物流活动顺利进行所不可缺少的。
特点:(1)物流信息量大、种类多、分布广,信息的产生、加工、传播和应用在时间、空间上不一致,方式也不相同,物流信息的收集、分类、筛选、统计、研究等工作的难度加大。
(2)物流信息动态性强、实施性高,信息价值衰减速度快、时效性强.(3)物流信息趋于标准化。
作用:(1)物流信息的传送连接着物流活动的各个环节,并指导各环节的工作,起着桥梁和纽带的作用.(2)物流信息可以帮助企业对物流活动各环节进行有效的计划、协调和控制,以达到系统整体优化的目的。
(3)物流信息有助于提高物流企业科学管理和决策的水平。
1。
1。
2物流信息技术:物流信息技术是指运用与物流活动各环节中的信息技术。
物流信息系统:物流信息系统是指由人员、计算机硬件、软件、网络通讯设备及其他办公设备组成的人机交互系统.1。
3物流信息系统的支撑技术:(1)物流信息采集与识别技术(2)物流信息交换与传输技术(3)物流信息存储与处理技术1。
5物流信息系统的地位和作用:(1)大幅提升企业形象,建立现代化信息管理体制。
(2)规范并优化企业内部各部门、各办事机构的业务流程,再造业务规范,对重点业务实行全面质量监控.(3)实现各部门的协作、无纸办公。
(4)使企业内部各部门使用权限明了,杜绝相互推诿现象。
(5)开发决策支持系统,为企业决策层提供图形化、报表化的市场分析数据,能够对未来的业务发展、客户需求发展、市场发展做出预测.(6)预留标准的EDI数据接口,可以方便的实现与关系部门的数据共享和交换.(7)建立企业Intranet/Internet网络平台。
(8)通过Internet实现全天候实施服务,充分满足客户的各种需求,全面提升客户服务水平,大大加强与客户的紧密度,将应用企业塑造成国际化企业的首选品牌。
C++继承机制继承继承是类与类之间的一种关系定义:“类B继承类A”,或者说“类A派生类B”类B中除了自己定义的成员之外,还自动包括了类A中定义的数据成员与成员函数,这些自动继承下来的成员称为类B的继承成员。
一、继承的语法1、class 派生类名: 基类类名表{public: 公有成员说明列表;protected: 受保护成员说明列表;private: 私有成员说明列表;};其中基类类名表的格式为:access 基类类名1, ……, access 基类类名naccess为继承访问控制符,规定了派生类对基类的继承方式,可为public,private或者protected,继承访问控制符可省略,此时认为为private在protected后定义的是保护段,其中的数据成员或成员函数称为受保护成员:具有公有成员与私有成员的双重角色。
2、一个类的受保护成员,对于其子孙类(派生类)的成员函数来说是公有的,对类本身及后代类之外定义的其他函数则是私有成员。
3、派生类可以重新定义基类的成员函数,覆盖基类的同名函数4.通过类名限定符在派生类中使用基类的同名成员二、继承访问控制规则公有继承(公有派生)、私有继承、保护派生类的对象不仅存放了在派生类中定义的非静态数据成员,而且也存放了从基类中继承下来的非静态数据成员。
二、类型兼容性1.赋值运算的类型兼容性类型的赋值兼容性规则:1) 允许将后代类的对象赋值给祖先类,但反之不成立。
例:BASE obj1;Y1 obj2;obj1 = obj2 ; // 把obj2中基类部分的内容赋给obj1obj2 = obj1 ;但此规则只适用于公有派生,只有公有派生类才能兼容基类类型2) 指向基类对象的指针也可指向公有派生类对象2.参数传递与对象初始化的类型兼容性与赋值运算类型兼容性相同A* p=q;//初始化A*p;P=q; //赋值继承与构造函数、析构函数一、构造函数与析构函数的调用次序1. 构造函数的调用次序在创建一个派生类的对象时先调用其基类的构造函数再调用本类对象成员的构造函数最后才调用本类的构造函数2. 析构函数的调用次序先调用本类的析构函数再调用本类对象成员的析构函数最后才调用其基类的析构函数二、向基类构造函数传递实际参数给基类构造函数传递实际参数是通过向派生类构造函数传递实际参数以及初始化列表来间接实现传递的。
C++——类继承以及类初始化顺序对于类以及类继承, ⼏个主要的问题:1) 继承⽅式: public/protected/private继承.这是c++搞的, 实际上继承⽅式是⼀种允许⼦类控制的思想. ⼦类通过public继承, 可以把基类真实还原, ⽽private继承则完全把基类屏蔽掉.这种屏蔽是相对于对象层⽽⾔的, 就是说⼦类的对象完全看不到基类的⽅法, 如果继承⽅式是private的话, 即使⽅法在基类中为public的⽅法.但继承⽅式并不影响垂直⽅向的访问特性, 那就是⼦类的函数对基类的成员访问是不受继承⽅式的影响的.⽐较(java): java是简化的, 其实可认为是c++中的public继承. 实在没必要搞private/protected继承, 因为如果想控制,就直接在基类控制就好了.2) 对象初始化顺序: c++搞了个成员初始化列表, 并确明确区分初时化跟赋值的区别. c++对象的初始化顺序是:(a) 基类初始化(b) 对象成员初时化(c) 构造函数的赋值语句举例:假设 class C : public A, public B {D d;//}则初始化的顺序是A, B, D, C的构造函数.这⾥基类的初始化顺序是按照声明的顺序, 成员对象也是按照声明的顺序. 因此 c(int i, int j) : B(i), A(j) {} //这⾥成员初始化列表的顺序是不起作⽤的;析构函数的顺序则刚好是调过来, 构造/析构顺序可看作是⼀种栈的顺序;⽐较(java): java中初始化赋值是⼀回事. ⽽且对基类的构造函数调⽤必须显⽰声明, 按照你⾃⼰写的顺序.对成员对象, 也叫由你初始化.没有什么系统安排的顺序问题, 让你感觉很舒服;3) 多继承问题: c++⽀持多继承, 会导致"根"不唯⼀. ⽽java则没有该问题;此外c++没有统⼀的root object, java所有对象都存在Object类使得很多东西很⽅便. ⽐如公共的seriall, persistent等等.4) 继承中的重载: c++中, 派⽣类会继承所有基类的成员函数, 但构造函数, 析构函数除外.这意味着如果B 继承A, A(int i)是基类构造函数, 则⽆法B b(i)定义对象. 除⾮B也定义同样的构造函数.c++的理由是, 假如派⽣类定义了新成员, 则基类初始化函数⽆法初始化派⽣类的所有新增成员.⽐较(java): java中则不管, 就算有新增对象基类函数没有考虑到, ⼤不了就是null, 或者你⾃⼰有缺省值. 也是合理的.5) 继承中的同名覆盖和⼆义性: 同名覆盖的意思是说, 当派⽣类跟基类有完全⼀样的成员变量或者函数的时候, 派⽣类的会覆盖基类的.类似于同名的局部变量覆盖全局变量⼀样. 但被覆盖的基类成员还是可以访问的.如B继承A, A, B都有成员变量a,则B b, b.a为访问B的a, b.A::a 则为访问基类中的a. 这对于成员函数也成⽴.但需要注意的是, 同名函数必须要完全⼀样才能覆盖. int func(int j)跟int func(long j)其实是不⼀样的. 如果基类,派⽣类有这两个函数, 则不会同名覆盖.最重要的是, 两者也不构成重载函数. 因此假如A有函数int func(int j), B有函数int func(long j). 则B的对象b.func(int)调⽤为错误的. 因为B中的func跟它根本就不构成重载.同名覆盖导致的问题是⼆义性. 假如C->B=>A, 这⾥c继承B, B继承A. 假如A, B都有同样的成员fun, 则C的对象c.fun存在⼆义性. 它到底是指A 的还是B的fun呢?解决办法是⽤域限定符号c.A::fun来引⽤A的fun.另外⼀个导致⼆义性的是多重继承. 假设B1, B2都继承⾃B, D则继承B1, B2. 那么D有两个B⽽产⽣⼆义性.这种情况的解决办法是⽤虚基类. class B1 : virtual public B, class B2:virtual public B, D则为class D : public B1, public B2. 这样D中的成员只包含⼀份B的成员使得不会产⽣⼆义性.⽐较(java). java中是直接覆盖. 不给机会这么复杂, 还要保存基类同名的东西. 同名的就直接覆盖, 没有同名的就直接继承.虚基类的加⼊, 也影响到类的初始化顺序. 原则是每个派⽣类的成员化初始化列表都必须包含对虚基类的初始化.最终初始化的时候, 只有真正实例化对象的类的调⽤会起作⽤. 其它类的对虚基类的调⽤都是被忽略的. 这可以保证虚基类只会被初始化⼀次.c++没有显式接⼝的概念, 我觉得是c++语⾔的败点. 这也是导致c++要⽀持组件级的重⽤⾮常⿇烦. 虽然没有显式的接⼝, 但c++中的纯虚函数以及抽象类的⽀持, 事实上是等同于接⼝设施的. 当⼀个类中, 所有成员函数都是纯虚函数, 则该类其实就是接⼝.java c++接⼝类(所有成员函数都是纯虚函数)抽象类类(部分函数是虚函数)对象类对象类C++构造函数调⽤顺序1. 如果类⾥⾯有成员类,成员类的构造函数优先被调⽤;2. 创建派⽣类的对象,基类的构造函数优先被调⽤(也优先于派⽣类⾥的成员类);3. 基类构造函数如果有多个基类,则构造函数的调⽤顺序是某类在类派⽣表中出现的顺序⽽不是它们在成员初始化表中的顺序;4. 成员类对象构造函数如果有多个成员类对象,则构造函数的调⽤顺序是对象在类中被声明的顺序⽽不是它们出现在成员初始化表中的顺序;5. 派⽣类构造函数,作为⼀般规则派⽣类构造函数应该不能直接向⼀个基类数据成员赋值⽽是把值传递给适当的基类构造函数,否则两个类的实现变成紧耦合的(tightly coupled)将更加难于正确地修改或扩展基类的实现。
Java基本概念:多态⼀、简介描述:多态性是⾯向对象编程中的⼀个重要特性,主要是⽤来实现动态联编的。
换句话说,就是程序的最终状态只有在执⾏过程中才被决定,⽽⾮在编译期间就决定了。
这对于⼤型系统来说能提⾼系统的灵活性和扩展性。
多态允许相同类域的不同对象对同⼀消息做出响应。
即同⼀消息可以根据发送对象的不同⽽采⽤多种不同的⾏为⽅式。
多态可以让我们不⽤关⼼某个对象到底是什么具体类型,就可以使⽤该对象的某些⽅法,从⽽实现更加灵活的编程,提⾼系统的可扩展性。
如果对象的编译时类型和运⾏时类型不⼀致,就会造成多态。
存在条件:1. 类之间有继承关系。
2. ⼦类重写⽗类⽅法。
3. ⽗类引⽤指向⼦类对象。
注意:多态是⽅法的多态,属性没有多态性。
⼀个对象的实际类型是确定的,但是可以指向这个对象的引⽤的类型,却是可以是这对象实际类型的任意⽗类型。
⼦类继承⽗类,调⽤⽅法,如果该⽅法在⼦类中没有重写,那么就是调⽤的是⼦类继承⽗类的⽅法,如果重写了,那么调⽤的就是重写之后的⽅法。
'protected'修饰的⽗类⽅法可以被⼦类见到,也可以被⼦类重写,但是它是⽆法被外部所引⽤的,所以没有多态性。
通过⼀个变量调⽤其引⽤的对象的⼀个⽅法,编译器是否能让其编译通过,主要是看该变量类型的类中有没有定义该⽅法,如果有则编译通过,如果没有则编译报错。
⽽不是看这个变量所引⽤的对象中有没有该⽅法。
Java中的⽅法调⽤,是运⾏时动态和对象绑定的,不到运⾏的时候,是不知道到底哪个⽅法被调⽤的。
编写程序时,如果想调⽤运⾏时类型的⽅法,只能进⾏类型转换,不然通不过编译器的检查。
但是如果两个没有关联的类进⾏强制转换,会报类型转换异常:ClassCastException。
⽰例:public class Test {public static void main(String[] args) {/* 编译看左,运⾏看右 */Student student = new Student();/* 变量person是可以指向Person类型或其⼦类型的对象,所以可以指向Student类型对象 */Person person = new Student();/* 变量student能调⽤的⽅法是Student类中有的⽅法(包括继承过来的) */student.say();//Student/* 变量person能调⽤的⽅法是Person类中有的⽅法 */person.say();//Student}}class Person {public void say() {System.out.println("Person");}}class Student extends Person {public void say() {System.out.println("Student");}}⼆、重写、重载、多态的关系1. 重载是编译时多态调⽤重载的⽅法,在编译期间就要确定调⽤的⽅法是谁,如果不能确定则编译报错。