比較分析C++、Java、Python、R語言的面向物件特徵,這些特徵如何實現的?有什麼相同點?
一門課的課後題答案,在這裡備份一下:
面向物件程式設計語言
– 比較分析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的面向物件系統中類型別物件之間不提供動態轉換機制;而是採用名-值(物件)動態約束機制。
保持更新,資源來源於網路。