MATLAB面向對象編程是什麼樣的體驗?

聽說過MATLAB支持面向對象編程。

1、不知道有沒有什麼坑,聽說運行速度比較慢,最近可能速度有所提高。

2、OOP在這麼情況下有優勢,什麼情況下是個負擔?請舉例說明。

希望有過MATLAB面向對象編程經歷的人分享一下經驗。


作為《MATLAB面向對象編程-從入門到設計模式的作者》,如下的問答可以幫你大致了解在MATLAB中面向對象編程的能給你帶來什麼

【問題】我是理工科學生,MATLAB用的很熟練,我有必要學面向對象編程嗎?

【回答】我們的書籍主要面向的就是理工專業的學生學者,我們希望通過介紹MATLAB OOP來幫助他們更好的解決科研中的問題。或許你曾有這種感覺: 在科研和學習中,寫的程序一但到達一定的規模,維護起來就會很困難, 調試越來越慢。隨著 科研項目不斷有新的要求,程序在不斷的修改和擴展; 函數多達上百個; 一旦有修改則牽一髮則動全身; 有的時候甚至需要做傷筋動骨的修改。MATLAB 的面向對象編程和設計就是專門幫你解決中這種問題的,我們這本書的重點不是介紹一個函數或者技巧,這本書的重點是怎樣從整體上去設計我們的程序,小到一個家庭作業,一個兩個星期的項目,大到碩士或者博士的畢業設計,一個大型的多人合作的項目。面向對象的思想讓你從繁重的程序維護中解脫出來,讓你的注意力放到真正需要解決的問題之上,把需要解決的問題解決好。再次重申,我們不是為了學習面向對象而學習面向對象,作為科研人員,我們都以高效務實為目標,如果一個技術能夠讓我們投資少量的時間去學習,並且學會了之後讓我的科研工作如虎添翼,讓我有更多的時間做其它事情,何樂而不為呢。

【問題】面向對象編程難道不是只有計算機專業的人才用的嗎?

【回答】計算機專業背景的科研人員使用面向對象語言編程是一個自然的選擇,因為面向對象可以更好的幫它們解決軟體設計的問題。但是面向對象的方法並不是軟體行業所獨有的,面向對象可以被任何學術背景的研究人員使用,適合解決各個行業的學術問題。由於目前主流的面向對象語言比如C++ JAVA學習周期比較長,面向對象的方法和設計思想被繁瑣的語法隱藏了起來,大多數非CS專業背景的研究人員沒有這樣的時間和精力去先學習C++和JAVA的語法,然後再學習面向對象的編程思想,進而再使用的實際的科研工作中來。而且在科學工程計算中,MATLAB才是主流的語言。MATLAB從2008a之後開始真正的支持面向對象編程。MATLAB的提供了這樣一個寶貴的機會,它能夠讓我們避開繁瑣的語法,直接接觸到核心的面向對象和設計模式的思想。所以這句話應該這麼說,使用MATLAB語言,你不需要CS的專業知識也能學會面向對象和實際模式。

【問題】MATLAB已經很簡單了,為什麼我還要學面向對象的MATLAB

【回答】MATLAB致力於提供給用戶簡單的語法,使得用戶上手快,編程語言和實用語言更加的貼近自然語言,但是這並不代表我們要解決的科研問題是簡單的。面向對象是一種系統化編程的思路,教你一開始就去系統化的設計你的程序,設計模式給你提供了十幾種解決複雜問題的套路,如果你能把這些套路使用在你的科研工作編程中,你的科研工作必將如虎添翼。

【問題】學習MATLAB面向對象需什麼樣的基礎

【回答】我們寫本書的目的就是要做到讓具有初級的MATLAB語言基礎的讀者能夠迅速地一步到位把面向對象的思想滲透到自己的編程習慣中去。其實只要懂得什麼是變數,什麼是函數,就完全能夠開始學習MATLAB OOP了。對於有經驗的讀者,就是那些熟悉MATLAB語言和各種toolbox的讀者,我們的MATLABOOP書能夠讓他們更深入的了解MATLAB的體系,提高自己的對程序的總體設計,做到事半功倍。

【問題】面向對象編程是不是要花很多時間學啊?我還有研究課題要做,沒有這麼多時間啊

【回答】本書的作者都是理工科的背景,秉持高效務實的做事風格,完成每一項工作都非常的注重成本,也就是所花的時間。我們完全沒有興趣編寫一本全面詳盡,但是閱讀起來費時費力的書,這樣的書也不會受到我們目標讀者的歡迎。讓讀者用最短的時間入門面向對象,讓讀者用最小的成本學會面向對象的中級基礎,並且能夠順利的進入到編程思想的學習當中去,越過面向對象語法上的障礙,真正的享受使用面向對象的編程方法。才是我們的目的。我們還盡量的讓書中內容的編排便於查找,讀者完全可以跳躍性的閱讀自己需要的內容,當工作變得複雜,需要更多MATLAB面向

對象編程語言特性的時候再會夠頭來查找。

【問題】面向對象編程難學么?或者說,我要學多久才能用到實際的 編程中

【回答】面向對象的思想並不難,但是目前主流的面向對象的語言比如C++和JAVA,在語法上的繁瑣使得面向對象這塊寶藏被隱藏在了各種語法規定的後面。MATLAB的面向對象語言的支持提供了前所未有的機會,讓我們能夠迅速的越過這些障礙,真正學習編程的思想。眾所周知,學習一門語言不但需要學習語言的語法,還需要不停的實踐。 對於廣大的研究人員,MATLAB是一門主流的科學計算的語言,你學習了MATLAB 面向對象的語法,第二天就可以直接使用到自己的科研編程中去,哪怕是一個簡單的擬合,做圖,你都可以用使用OOP的思想把你的程序組合起來,你自己的科研就是實踐編程思想的最好的平台,好的編程思想可以讓你的科研工作事半功倍。

MATLAB 作為一個高級的工程科學計算軟體,給你提供了前所未有的,在以往只有CS專業背景的人才能夠具有的實踐編程思想的機會。

【問題】MATLAB的面向對象編程和C++和JAVA的面向對象編程有什麼不一樣嗎?

【回答】MATLAB作為一個商業軟體,提供面向對象編程的支持,這和C++和JAVA有本質的不同,C++和JAVA給用戶提供"基石",用戶需要花大力氣去首先學習其語法,然後學用這些"基石"的組合來解決複雜的問題,這需要一個較長的學習周期才能上手,這需要相當深厚的基礎知識和時間,而大部分的科研工作者沒有這樣的時間和精力去專門學習一門語言來幫助他們解決問題。

MATLAB提供了這樣一種渠道,把這些基石進行相當複雜的組合,然後當作一個語言的特殊功能提供給用戶。我們只需要多這些特殊功能稍加了解,就可以很快掌握,這是一種務實的精神,

我們需要在有限的時間內,以最高的效率完成任務。本書還會簡單解釋一些這些特殊的功能是來自何方,大概是怎麼實現的,目的是為了幫助讀者更好的使用這些功能。

【問題】面向對象編程和書中的設計模式是一回事嗎?

【回答】面向對象是相對於面向過程的一種編程方式,設計模式是建立在面向對象基礎之上的針對

一些常見的複雜問題的抽象解決方法。問題再複雜,都可以被分解成小的部分加以抽象,然後使用設計模式來高效的解決。有的時候是多種設計模式的結合。

【問題】MATLAB面向對象不是有一本英文的用戶手冊嗎,你們的這本書和這本英文手冊比有什麼優點

【回答】本書部分參考了英文MATLAB面向對象的用戶手冊中的內容,並在此之上做了大量的改進,使其能夠為更多理工科用戶學習和閱讀。具體說來,:首先這本用戶手冊有500多頁英文,通讀起來不是一件容易的事情。第二它只介紹了基本的MATLAB基本的面向對象技術,沒有介紹設計模式,而設計模式才是真正利用OOP的試金石。第三因為OOP的編程和設計模式已經是很成熟的技術,我們還參考了大量的C++,JAVA的面向對象的編程書籍,和設計模式的書籍,我們有信心這本MATLAB OOP的數據將比MATLAB OOP的英文手冊更加的面向中文讀者,而且學習和閱讀的成本很低,就是說我們的目的就是讓讀者花很少的時間和精力去學習並且掌握MATLAB OOP.


有空慢慢答……

首先一句話MATLAB對象非常有用。

MATLAB的handle類型對象可以類似指針使用,繪圖大部分東西(figure、axes)也都是handle子類所生成的對象。你說用指針傳遞句柄和MATLAB普通變數按值傳遞哪個快?就算不快也不會慢吧


我曾經做過一個用MATLAB實現過一個Agent Based model,主要用來模擬銀行,存款者和貸款者之間的關係。剛開始的時候嘗試過把銀行,存款者和貸款者分裝成三個類,然後,實例化10個銀行,2000個貸款者和20000個貸款者。由於在整個過程中需要層層的迭代和賦值,導致計算的速度奇慢:計算1000次迭代需要2~3天的時間(當時我用的是2014版的MBP,MATLAB是2014B)。最後把所有的類全部轉化成了structure,並且儘可能的吧所有的循環都改寫成矩陣相乘的形式,速度得到了很大的提高,基本上能在一個小時以內解決問題。

我覺得每一個語言都有自己的特性。對於MATLAB而言,良好的矩陣編程是它的特性,我們在編程的時候要儘可能的從矩陣計算的角度考慮。OOP算是MATLAB支持的一個特性,在計算的速度和優化上,的確沒有專門的OOP語言有優勢,特別是在大量計算的情況下。


matlab面向對象編程支持不錯,但是主要是在matlab平台下運行,用於開發工具箱(工具箱就是不適合編譯發布的軟體,只在ml平台下運行)曾在matlab發布會中了解到這個oop在國外用的比較多,自己也用過相關的第三方oop的工具箱。自己用matlab的面向對象編寫過簡單的應用程序和遊戲,感到matlab oop實在是oop中的典範,支持幾乎一切oop特性,比c++java可以用更完善的語法編程,支持實物類和指針類(不知道是不是這麼翻譯),支持傳遞事件消息,和自帶的

gui融合很好(但是gui只具備基本功能,更多功能還是要用java插件我沒用過),可以調用豐富的工具箱,等等。所以如果要在matlab里開發工具箱,那麼oop實在太好用了。只是在國內ml oop比較小眾,畢竟是廣大工程師在用ml,大部分不懂oop,而國內又沒有自己開發ml工具箱的傳統。


不算用的特別多,用matlab寫過一個自動生成實驗報告的程序。

所以可以談談初學者的體驗。

不可否認,OOP還是工程上一項很不錯的發明。有了OOP,你可以寫

很多更複雜的程序。如果沒有OOP,我不知道我那個東西應該怎麼寫,

即使寫出來的,用起來肯定也會非常困難。

但就體驗來時說,語法還是有點亂,當然整個matlab都有點這個感覺。

------------------

最後,終於可以把幾個函數寫在一個文件里了。


沒什麼大的不同,就是容易分心,畢竟對象比較漂亮。


轉載自MATLAB面向對象編程:類與對象

類(class)

類是一種數據類型,與普通的數據類型不同的是類不僅包含數據,還包含對數據的操作,類把數據和數據操作方法封裝在一起,作為一個整體參與程序的運行。類具有可繼承性,創建一個新的類的時候,可以在一個基類中添加成員派生出新類。類的變數和類的實例是不同的,類的實例是動態分配在內存區域,通常稱類的實例為「對象」,同一個類可以有不同的實例存在,他們各自有自己的數據,但是數據操作方法是相同的。類的變數可以看作是一個指針,指向類的實例。

在MATLAB中,為了更好地進行數據的封裝,更加抽象地描述對象,也定義了類。

1 建立一個類

通常一個類應該包含四個基本的成員函數:

構造函數 ―― 與類名相同,可以在其中完成成員初始化的工作;

顯示函數 ―― 名為display,用於顯示成員的數據;

賦值函數 ―― 名為set,用於設置類成員的數值;

取值函數 ―― 名為get,用於讀取類成員的函數。

與C++的類不同的是,MATLAB的類不需要特別的析構函數。如果類用到了一些特殊的內容需要釋放的話,可以編寫一個成員函數,比如classclear,用包來釋放所佔用的資源。

下面用一個簡單的例子類介紹一些類如何使用。

例:定義一個名為list的類,它有兩個數據成員x和y,希望通過一個成員函數prod()來獲取x和y的乘積。本例的類是這樣的:

類名: list

成員變數:x,y

成員函數:

list:構造函數

display:顯示函數

get:取值函數

set:賦值函數

prod:計算函數

現在就來建立它。

(1) 在工作目錄上建立一個子目錄(以筆者的習慣為例):

cd E:MyProgrammatlab7chap4

mkdir @list %創建新的文件夾,名為@list

類名前面要加上一個字元"@』,對於這樣形式的目錄里所有保存的M文件,MATLAB都認為是類的成員函數。

(2) 編寫5個成員函數的M文件保存在E:MyProgrammatlab7chap4@list 目錄下:

[plain] view
plaincopy
% 構造函數list.m:x和y的初始化, function 返回變數=函數名(輸入變數)
function d = list(x,y)
d.x=x;
d.y=y;
d=class(d,"list");

% 顯示函數display.m
function display(d) %無返回變數
fprintf("list class:
");
fprintf("x=%d
",d.x); %
fprintf("y=%d
",d.y);

% 獲取函數get.m
function val = get(d,prop_name) %function 返回變數=函數名(輸入變數)
switch prop_name %變數名可能是x,也可能是y
case "x"
val=d.x;
case "y"
val=d.y;
otherwise
error([prop_name,"is not a valid list property"]);
end
%set.m
function d = set(d,varargin) %function 返回變數=函數名(輸入變數)???
argin=varargin;
while length(argin)&>=2,
prop=argin{1};
val=argin{2};
argin=argin(3:end);
switch prop
case "x"
d.x=val;
case "y"
d.y=val;
otherwise
error("Asset properties:x,y");
end
end

%prod.m
function z=prod(d)
z=d.x*d.y;

(3) 在MATLAB命令行中進行如下操作:

[html] view
plaincopy
d = list(11,22)
list class:
x=11
y=22
prod(d)
ans =
242
d = set(d,"x",7);
get(d,"x")
ans =
7
prod(d)
ans =
154

下面對操作步驟中的細節加以詳細解釋。

1.1. 類的創建

創建一個新的類,首先需要在構造函數中用結構類型struct建立一個結構變數,包含所需要的成員變數。注意,這裡不用考慮成員函數(只考慮數據成員)。然後用class命令將其轉換成類,並返回。class命令的語法很簡單:

類變數 = class(結構變數,"類名");

這裡類名和構造函數名相同(上例中都為list)。

程序中要創建這個類的新的變數時,只需調用其構造函數,返回的變數就屬於這個類的了。當然,這裡的list.m太過簡單,沒有任何變數檢查,使用中還可以根據情況添加一些擴充功能。

1.2. 類成員變數的賦值

本例中,類的成員變數是在構造函數中賦值的。MATLAB中,類成員變數都是private的,必須在成員函數中訪問,因此就不能像struct那樣,用d.x和d.y等形式訪問其成員變數了。不過,這個問題不嚴重,編寫一個專門的成員函數get函數就行了(跟C++一樣對數據進行了保護)。另外,成員函數的調用跟普通的函數一樣。注意在get和set函數中,成員變數是以字元串的形式指定的,要通過字元串比較的辦法進行區分,然後對輸出變數進行賦值。本例中的set函數支持同時對兩個成員變數賦值,因此用到了不定長輸入產生表varargin,例如:

d = set(d,"x",12) % 只對其中一個成員變數賦值

list class:

x=12

y=22

d = set(d,"x",23,"y",34) % 同時對兩個成員變數賦值

list class:

x=23

y=34

1.3. 成員變數的顯示

成員變數display不是必須的,不過它可以顯示類的有用信息。如果在命令行上輸入一個類變數,不加分號就回車,這時其display函數就自動調用。在該函數中,可以顯示任何與該類信息相關的信息,當然也可以是不相關的。

1.4. 工作目錄

一個工作目錄下可以放置多個類目錄。通常可以把大程序按功能分開,用類重新組織起來,使程序更具有結構化,增強其可讀性。

2 在類中引用方法(方法:就是成員函數)

2.1. 實現方法函數

類的方法(class methods)是指M文件編寫的以類的對象作為輸入產生的函數。

在OO中,我們說一個類有方法和欄位,也可以說它有成員函數和成員變數,函數和變數是程序層面的術語,而方法和欄位是設計層面的術語,即方法=成員函數,欄位=數據成員。一個特定的類的方法通常要保存在這個類的目錄中。如上一小節中

@list 的方法函數存儲在 @list路徑下。

對方法的調用方式和對普通函數的調用方式是相同的,其命令格式為:

[輸出1,輸出2,…] = 方法名稱(對象名,參數1,參數2,…);

但是必須注意,方法函數中如果對類的成員變數進行了改變(set),就必須將改變後的類變數作為輸出變數返回,否則在原工作空間中的類變數的成員變數不能得到更新。例如:

???

d = list(10,20);%調用構造函數構造了一個list類型的對象d,d.x=10,d.y=20

set(d,"x",23,"y",34);

d

list class:

x=10

y=20

可以看到,調用set函數而不將返回結果重新賦值給d,著d的x和y兩個成員變數仍然保持原來的數值。

2.2. 私有方法(私有成員函數)

私有方法是指只能被同類的其他方法所調用的方法,其對應的M文件存在類目錄的private子目錄下。例如,如果list類有私有方法,就應該將它們保存在@list/private目錄下。私有方法的作用域子限於list這個類中,而不能夠被MATLAB命令行調用,或者被上一層類的方法調用。

2.3. 輔助函數

在設計類的時候,有些工作需要由一些特定的函數來完成,但這些函數並不一定直接對類的對象操作,這些函數通常被稱為輔助函數(helper funtions)。輔助函數可以是類方法文件中的一個子函數,也可以是一個獨立的私有函數。

2.4. 類方法的調用

在MATLAB中,可以採用與調試程序相同的命令對類方法進行調試,唯一不同的是對類方法的調試必須在命令行中添加類的路徑。例如使用dbstop命令(停止調試)對display進行調試的時候,需要用如下的命令:

dbstop @list/display

當然,也可以在M文件編輯/調試器中直接設置斷點進行調試。

3 類的繼承和集成

MATLAB中的類對象可以集成其他類對象的屬性,當一個子類從父類中繼承了屬性後,在子類中將包括父類的所有成員和方法。繼承的概念是面向對象編程中的一個重要特性,子類可以很方便的引用父類中已經定義的方法。類的繼承由兩種方式:簡單繼承和多重繼承。類集成的概念有點類似於嵌套,是指類對象的域中包括另外一個對象的情形。

3.1. 簡單繼承

簡單繼承是指子類從一個父類繼承屬性,子類中也包括它自己的一些新的屬性。對於父類的操作可以應用到子類上來,而對於子類中不屬於父類的方法則不可以應用到父類上去。

通常可以使用class函數來實現類的繼承。

子類對象名 = class(子類對象名,"子類類名",父類對象名);

3.2. 多重繼承

多重繼承是指子類從多於一個父類中繼承屬性。子類中包含所有從父類中繼承來的屬性,還包括它自己的屬性。

3.3. 類的集成

  1. 類的集成是指一個類可以把另外的類作為自己的一個成員變數。被嵌入的類對象的方法函數值能通過外層對象的方法函數調用。


好像@暑假幫我幹活的兩個小弟。。。他們正在干這事,寫數據處理程序,用OOP。

但是他們沒空答呀。


體驗就是花了兩個晚上幫自己完成了一個簡單的航路飛機監控以及進近警告模型。隨便帶妹。。雖然至今不知道那句下次請吃飯就是指下次我再幫她做事然後請我吃飯,還是指下次遇見了請我吃飯。。。


Matlab的OOP很好、很全面,用起來也很方便。可惜很多人都不會。


以前常常糾結於「這個方法到底是寫成成員函數呢,還是放外面比較好」這樣的問題。在看過Bishop Pattern Recognition Machine Learning 的包之後,我才知道原來科學計算的OOP是這樣用的。

這個包的組織邏輯是:將Generic方法和處理對象分開。Generic方法用函數來寫,處理對象用類來寫。這樣,寫好的函數就可以反覆使用,甚至發表。而class每次要根據需求現寫(當然也可以留著為同樣的需求服務)。

PS:但是我覺得在科學計算領域裡 學習比如說像JAVA里那種的OOP編程,是不可能的。因為本身就不是一種東西。(也可能是因為我才疏學淺)

PRML包的地址:

https://www.mathworks.com/matlabcentral/fileexchange/55826-pattern-recognition-and-machine-learning-toolbox


用過MATLAB面向對象做過一個股票回測的小玩意兒,發現MATLAB做面向對象還挺方便的。之前用MATLAB根本沒有考慮過面向對象的事兒,不過自從了解之後就已經有點後悔之前做過的一些東西沒用上了,如果用面向對象來寫會舒服很多。。。


用起來還是比較方面的,語法也比較簡單。我是用來做網路模擬(隨機事件),不過做到最後還是放棄了,全轉為用C++來寫,遇到的坑是成員函數給成員變數賦值沒有辦法直接賦值,我用的版本是2009a的,當時貌似只能夠set或者get直接獲取成員變數的值。所以每一次成員變數的賦值都很耗時間,從而效率變得很低(和C++比差距非常大,當時這塊成員變數複製沒有處理好)。


一般小規模的問題解決,直接函數式就好了,速度的話看你需求,我個人完全能接受。matlab 提供了1.並發2.集群3.編譯成c/java來解決速度問題。同時,大量函數都已經被改寫成了更快速度的c。

面向對象給我的感覺就是小規模的問題,有搞完對象的時間,我事都完了…


推薦閱讀:

如何評價12月22日上線的計蒜客 "CS 212: 面向對象的程序設計 (C++)"?
為什麼程序員覺得自己學的那門語言就是最好的?
靜態方法能被兩個方法同一時刻調用嗎?
C++寫光柵化渲染器遇到些問題?
如何高效學習並掌握現代C++?

TAG:編程 | MATLAB | 面向對象編程 | 編程學習 | X是種怎樣的體驗 |