一门课的课后题答案,在这里备份一下:
面向对象程序设计语言
– 比较分析C++、Java、Python、R语言的面向对象特征,这些特征如何实现的?有什么相同点?
C++ 语言的面向对象特征:
对象模型:封装
(1) 访问控制机制:
C++提供完善的访问控制机制,分别是: public,protected和private。
private, public, protected 访问标号的访问范围 |
||
public |
可访问 |
1.该类中的函数 ; 2.子类的函数; 3.其友元函数访问;4.该类的对象访问; |
protected |
可访问 |
1.该类中的函数;2.子类的函数; 3.其友元函数访问; |
不可访问 |
1.该类的对象访问; |
|
private |
可访问 |
1.该类中的函数;2.其友元函数访问; |
不可访问 |
1.子类的函数;2.该类的对象访问; |
(2) 对象的独立性:
C++中对象本身不具有独立性,也就是对象必须属于某一个类;
(3) 类本身是不是对象?
C++中类本身不是对象,对象是类的实例化;
(4) 基于类的模型,还是基于对象或原型的模型?
C++是基于类的模型
对象模型:继承
(1) 类层次结构:采用单根的类层次结构,还是任意的类层次结构?
C++采用任意的类层次结构;
(2) 继承方式:提供哪些继承方式?
C++采用三种继承方式,分别是public继承,protected继承,private继承;
public |
protected |
private |
|
public继承 |
public |
protected |
不可用 |
protected继承 |
protected |
protected |
不可用 |
private继承 |
private |
private |
不可用 |
(3) 采用基于继承的模型,还是基于指派的模型?
C++是基于继承的模型
(4) 允许多重继承?还是只允许单继承?
C++允许单继承、多继承、多重继承和虚继承;
在单继承中,每个类可以有多个派生类,但是每个派生类只能有一个基类,从而形成树形结构;
C++使用虚拟继承,解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类。
对象模型:多态
多态:是指同样的消息被不同类型的对象接收时导致不同的行为。
(1) 类属:虚函数
用父类的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数,这种技术可以让父类的指针有“多种形态”;
(2) 类属:模板函数
模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。
(3) 重载:同名函数
有两个或多个函数名相同的函数,但是函数的形参列表不同。在调用相同函数名的函数时,根据形参列表确定到底该调用哪一个函数。
C++语言不是“纯粹”的面向对象语言:
1) main函数不在任何类里面;
2) 基本的数据类型不是对象;
3) 友元会破坏封装性;
4) 支持独立的函数,数据,即过程化编程
变量的语义模型:
C++采用的是值模型,可以创建静态对象或栈对象;
但只有通过对象引用或指向对象的指针才能实现面向对象的动态约束行为。
C++支持静态对象和自动对象:
静态对象:变量定义在函数外或是用static关键字修饰的变量存放在静态存储区。放在静态存储区的数据在整个程序运行期间持续有效。
自动对象:C++默认局部变量的生命期局限于所在函数的每次执行期间。只有当定义它的函数被调用时才存在的对象成为自动对象。自动对象在每次调用函数时创建和撤销。
C++ 不依赖自动废料收集(GC):
大多数 OO 语言都依赖于自动存储回收系统;
C++是例外,其设计目标之一是尽可能避免对自动存储回收的依赖,以支持系统程序设计,提高效率,减少运行时间上的不确定性。
C++提供静态约束(默认)和动态约束两种方式;
C++提供的类类型对象的转换形式如下:
dynamic_cast<T>(expression): dynamic_cast 主要用来执行“安全向下转型”(Safe downcasting),也就是用来决定某对象是否归属继承体系中的某个类型;
C++类类型对象的动态转换机制:
1) 子类向基类的向上转型(Up Cast)
2) 基类向子类的向下转型(Down Cast)
3) 横向转型(Cross Cast)
Java 语言的面向对象特征:
对象模型:封装
(1) 访问控制机制:
Java提供完善的访问控制机制,分别是: public,protected、friendly和private。
Java类中成员修饰符的访问权限 |
||||
public |
protected |
friendly |
private |
|
本类 |
√ |
√ |
√ |
√ |
本包 |
√ |
√ |
√ |
× |
子类 |
√ |
√ |
× |
× |
其他 |
√ |
× |
× |
× |
(2) 对象的独立性:
Java中对象本身不具有独立性,也就是对象必须属于某一个类;
(3) 类本身是不是对象?
Java中类本身不是对象,对象是类的实例化;
(4) 基于类的模型,还是基于对象或原型的模型?
Java是基于类的模型;
对象模型:继承
(1) Java采用单根的类层次结构:
单根层次结构:在Java中,所有类都应从单独一个基础类继承,终级基础类为“Object”。
(2) 继承方式:Java只有普通的extends继承方式
当创建一个类时,总是在继承,如果没有明确指出要继承的类,就总是隐式地从根类Object进行继承。
(3) 采用基于继承的模型,还是基于指派的模型?
Java是基于继承的模型
(4) 允许多重继承?还是只允许单继承?
Java中类允许单继承和多重继承;
在单继承中,每个类可以有多个派生类,但是每个派生类只能有一个基类,从而形成树形结构;
Java中接口允许多继承;
对象模型:多态
多态:是指同样的消息被不同类型的对象接收时导致不同的行为。
(1) 类属:方法覆盖
覆盖实现多态性:通过子类对父类的重定义来实 现。方法的参数个数,类型,顺序要完全相同。
(2) 重载:同名函数
重载实现多态性:通过在一个类中定义多个同名的方法来实现。方法的参数个数,类型,顺序要有所不同。
Java是接近理想的语言,但希望在形式上尽可能靠近常规语言:
1) 不存在全局变量和全局函数;
2) main函数是类的方法;
3) 但,Java中基本数据类型以及类都不是对象。
Java除了基本类型外,变量采用引用模型,因此,Java没有必要再另外提供引用变量或指针变量机制;
Java支持静态对象和自动对象;
Java提供自动废料收集机制(GC);
Java中除了静态的方法以外,其他所有的方法都采用动态约束;
Java语言的类类型对象的动态转换机制如下:
向上转型:子类对象→父类对象
对于向上转型,程序会自动完成;格式如下:
父类 父类对象=子类实例;
向下转型:父类对象→子类对象
对于向下转型,必须明确的指明要转型的子类类型;格式如下:
子类 子类对象=(子类)父类实例;
Python语言的面向对象特征:
对象模型:封装
(1) 访问控制机制:
Python提供的访问控制机制,分别是: public和private;
Python中,如果函数、类方法和属性如果以两个下划线开头,但是不以两个下划线结束,它就是private的,其他的一切都是public的。
(2) 对象的独立性:
Python中对象本身不具有独立性,也就是对象一定属于某一个类;
(3) 类本身是不是对象?
Python中类本身是对象;
(4) 基于类的模型,还是基于对象或原型的模型?
Python是基于对象的模型;
对象模型:继承
(1) 类层次结构:采用单根的类层次结构,还是任意的类层次结构?
Python 2.2版本以后,采用单根的类层次结构;
单根层次结构:所有类是否都应从单独一个基础类继承?
在Python中,所有类都是Object类的子类
(2) 继承方式:提供哪些继承方式?
Python采用两种继承方式,分别是:
普通继承方式;
super继承方式;在super机制里可以保证公共父类仅被执行一次。
(3) 采用基于继承的模型,还是基于指派的模型?
Python是基于继承的模型
(4) 允许多重继承?还是只允许单继承?
Python允许单继承、多继承和多重继承;
在单继承中,每个类可以有多个派生类,但是每个派生类只能有一个基类,从而形成树形结构;
对象模型:多态
多态:是指同样的消息被不同类型的对象接收时导致不同的行为。
参数传递:通过动态束定机制
类属:通过Self指代对象本身
Python语言不是“纯粹”的面向对象语言:
1) 存在全局变量和全局函数;
2) main函数不是类的方法;
3) 但Python一切皆对象。
Python 采用的是引用模型:变量通过引用建立与对象的联系;
Python支持静态对象和自动对象;
静态对象
所有语言的全局变量都是静态对象;
在Python语言中:
使用global声明全局变量;
用同样的global语句可以指定多个全局变量,比如: global x, y, z。
Python依赖自动废料收集(GC);
Python默认采用引用计数来管理对象的内存回收。
当引用计数为0时,将立即回收该对象内存,要么将对应的block标记为空闲,要么返还给操作系统。
Python中所有方法的调用都是根据对象所指向对象的类型来动态的确定(Python变量的语义模型:引用模型)。因此Python所有的方法采用的是动态约束的方式。
类类型对象的动态转换机制:
Python的类类型对象之间不提供动态转换机制;而是采用名-值(对象)动态约束机制。
R语言的面向对象特征:
R语言的面向对象系统:
基于S3的面向对象编程
基于S4的面向对象编程
基于RC的面向对象编程
基于R6的面向对象编程
面向对象语言必须具有的基本特征:
封装、数据抽象、动态绑定、继承,仅具备上述二个或三个的,不能算是面向对象语言。
基于S3的面向对象编程:
是一种泛型函数的实现方式;
泛型函数是一种特殊的函数,根据传入对象的类型决定调研哪个具体的方法;
基于S3的面向对象编程,是一种动态函数调用的模拟实现。
由于基于S3的面向对象编程,并未提供封装机制。
因此,基于S3的面向对象编程不是严格意义上的面向对象语言。
基于S4的面向对象编程:
是一种标准的R语言面向对象实现方式;
S4对象有明确的类定义,参数定义,参数检查,继承关系,实例化等的面向对象系统的特征。
对象模型:封装
(1) 类的定义:在基于S4的面向对象系统中,类定义的格式如下:
setClass(Class, representation, prototype, contains=character(),validity, access, where, version, sealed, package,S3methods = FALSE, slots)
类的实例化
对象名<-new("类名",属性=属性值,...)
(2) 访问控制机制:
R语言中基于S4的面向对象系统,没有提供访问控制机制;
(3) 对象的独立性:
R语言中对象不具有独立性,也就是对象必须属于某一个类;
(4) 类本身是不是对象?
R语言中基于S4的面向对象系统中,类本身是对象;
(5) 基于类的模型,还是基于对象或原型的模型?
R语言中基于S4的面向对象系统是基于泛函的模型;
对象模型:继承
(1) 继承方式:提供哪些继承方式?
S4有比S3更为严格的继承关系,用contains 参数表示。
其具有单继承和多重继承两种继承方式;
单继承
多重继承
(2) 采用基于继承的模型,还是基于指派的模型?
R语言基于S4的面向对象系统是基于指派的模型;
R语言基于S4的面向对象系统是基于指派的模型;
对象模型:多态
通过泛函函数,实现方法的多态机制
R语言中的基于S4的面向对象系统,不是“纯粹”的面向对象语言:
1) 存在全局变量和全局函数;
2) main函数不是类的方法;
3) 但, R语言中的基于S4的面向对象系统中,一切皆为对象。
R语言中基于S4的面向对象系统,采用引用模型;
R语言中基于S4的面向对象系统支持静态对象和自动对象;
R语言中基于S4的面向对象系统依赖自动废料收集机制(GC);
R语言中基于S4的面向对象系统中所有的方法都采用动态约束;
类类型对象的动态转换机制:
R语言基于S4的面向对象系统中类类型对象之间不提供动态转换机制;而是采用名-值(对象)动态约束机制。
基于RC的面向对象编程:
1) RC对象系统从底层上改变了原有S3和S4对象系统的设计,去掉了泛型函数;
2) 真正地以类为基础实现面向对象的特征。
对象模型:封装
(1) 类的定义
定义的格式如下:
setRefClass(Class, fields = , contains = , methods =, where =, ...)
(2) 访问控制机制:
R语言中基于RC的面向对象系统,没有提供访问控制机制;
(3) 对象的独立性:
R语言中对象不具有独立性,也就是对象必须属于某一个类;
(4) 类本身是不是对象?
R语言中基于RC的面向对象系统中,类本身是对象;
(5) 基于类的模型,还是基于对象或原型的模型?
R语言中基于RC的面向对象系统是基于对象的模型;
对象模型:继承
(1) 类层次结构:采用单根的类层次结构,还是任意的类层次结构?
R语言基于RC的面向对象系统采用任意的类层次结构;
(2) 继承方式:提供哪些继承方式?
R语言基于RC的面向对象系统沿用R4的继承方式,用contains 参数表示;
其具有单继承和多重继承两种继承方式;
单继承
多重继承
(3) 采用基于继承的模型,还是基于指派的模型?
R语言基于RC的面向对象系统是基于继承的模型;
对象模型:多态
多态:是指同样的消息被不同类型的对象接收时导致不同的行为。
类属:方法覆盖
R语言中的基于RC的面向对象系统,接近“纯粹”的面向对象语言:
1) 不存在全局变量和全局函数;
2) 但,main函数不是类的方法;
3) R语言中的基于RC的面向对象系统中,一切皆为对象。
R语言中基于RC的面向对象系统,采用引用模型;
R语言中基于RC的面向对象系统支持静态对象和自动对象;
R语言中基于RC的面向对象系统依赖自动废料收集机制(GC);
R语言中基于RC的面向对象系统中所有的方法都采用动态约束;
类类型对象的动态转换机制:
R语言基于RC的面向对象系统中类类型对象之间不提供动态转换机制;而是采用名-值(对象)动态约束机制。
基于R6的面向对象编程
R6类型非常接近于RC类型(Reference classes),但比RC类型更轻;
由于R6不依赖于S4的对象系统,所以用R6的构建面向对象系统会更加有效率。
对象模型:封装
(1) 类的定义
在基于R6的面向对象系统中,类的定义和实例化的格式如下:
(2) 访问控制机制:
R语言中基于R6的面向对象系统,提供的访问控制机制,包括:public和private两种类型。
在类中访问公有成员时,需要使用self对象进行调用。
在类中访问私有成员变量时,要通过private对象进行访问。
(3) 对象的独立性:
R语言中对象不具有独立性,也就是对象必须属于某一个类;
(4) 类本身是不是对象?
R语言中基于R6的面向对象系统中,类本身是对象;
(5) 基于类的模型,还是基于对象或原型的模型?
R语言中基于R6的面向对象系统是基于对象的模型;
对象模型:继承
(1) 类层次结构:采用单根的类层次结构,还是任意的类层次结构?
R语言基于R6的面向对象系统采用任意的类层次结构;
(2) 继承方式:提供哪些继承方式?
R语言基于R6的面向对象系统的继承是通过inherit来实现 ,其具有单继承和多重继承两种继承方式;
单继承
多重继承
(3) 采用基于继承的模型,还是基于指派的模型?
R语言基于R6的面向对象系统是基于继承的模型;
对象模型:多态
多态:是指同样的消息被不同类型的对象接收时导致不同的行为。
类属:方法覆盖
R语言中的基于R6的面向对象系统,接近“纯粹”的面向对象语言:
1) 不存在全局变量和全局函数;
2) 但,main函数不是类的方法;
3) R语言中的基于R6的面向对象系统中,一切皆为对象。
R语言中基于R6的面向对象系统,采用引用模型;
R语言中基于R6的面向对象系统支持静态对象和自动对象;
R语言中基于R6的面向对象系统依赖自动废料收集机制(GC);
R语言中基于R6的面向对象系统中所有的方法都采用动态约束;
类类型对象的动态转换机制:
R语言基于R6的面向对象系统中类类型对象之间不提供动态转换机制;而是采用名-值(对象)动态约束机制。
保持更新,资源来源于网络。