Matlab - 具有抽象接口的面向对象 - 如何创建对象?
Posted
技术标签:
【中文标题】Matlab - 具有抽象接口的面向对象 - 如何创建对象?【英文标题】:Matlab - object orientated with abstract Interface - How creating object? 【发布时间】:2015-06-18 07:28:02 【问题描述】:你好可爱的社区,
我在这里很新,但仍然希望有人可以帮助我。我过去只是在 Matlab 上工作过,想做一个新项目。早些时候,我只是将所有内容存储在一个 Matlab 文件中,不需要使用类。现在已经改变了,所以我希望有人能解释我做错了什么。
我的愿望是创建基于项目对象。因此我开始在主文件夹中创建新文件夹:
C:\Users\Luftfahrt\MAV\
文件夹名称为:
+Data
+Model
读完第一章后
面向 MATLAB 的编程指南
我发现我正在使用加号创建公共对象。正是我想要的。在每个文件夹中,我插入了一个抽象接口和一个子接口。
DataLoaderIF
classdef DataLoaderIF< handle
methods (Abstract=true)
Data = LoadData(Asset,Start,End)
Status = getStatus(Obj)
Info = getInfo(Obj)
end
end
当我在上面运行这段代码时,他告诉我抽象类无法实例化,但我完全按照书中的方式进行了实例化。也许我想,从抽象接口运行代码是愚蠢的,所以没有问题,是吗?
DataLoader
classdef DataLoader < DataManager.DataLoaderIF
%Inheritent from DataLoaderIF. Is setting parameter and Importing
properties (Access=protected)
mStatus =-1; %nothing done
mInfo ='Import'; %
mData; %saving the imported data
mCollector; %to save the prices after structuring
end
methods
%creating the constructor
function Obj = DataManager
function getStatus(Obj)
mStatus=1;
end
function getInfo(Obj)
Info='Import';
mInfo= Info;
end
function LoadData(Asset,Start,End)
connection = yahoo;
mData= fetch(connection, Asset, Start,End, 'd');
close(connection)
%'JPY=X', '01-Jun-2011', datestr(now,'dd-mmm-yyyy'), 'd');
mCollector= ['date' 'open' 'high' 'low' 'close' 'volume' 'adj-close'
cellstr(datestr(mData(:,1))) num2cell(mData(:,2:end))];
end
end
我现在想做的是创建一个对象,然后给这个对象变量来执行获取。但是我现在如何实例化对象呢?他说我的构造函数是假的。
有人有什么想法吗?
附:我已经看过这里Documentation Matlab,但这并没有帮助我。
非常感谢!
【问题讨论】:
是错字还是您的构造函数缺少end
?
我只是在写一行代码的时候想,这个结尾是不是必须的?我错了吗?刚加了,还是不能实例化一个Object :(
DataManager 是抽象类吗?另外,你能更好地解释一下层次结构吗?我很难理解为什么你从 DataLoaderIF 继承然后使用 DataManager 构造函数。
看起来您的方法块中也缺少“结束”。另外,LoadData 不应该将“obj”作为第一个参数吗?
【参考方案1】:
目前尚不清楚您到底想做什么以及为什么需要一个抽象类而不是派生类,但假设您确实需要所有这些来实现比您描述的更多目的,请考虑以下几点:
根据 OOP 中的定义,抽象类不能被实例化。它只是从它继承的不同类的基本框架,您只能实例化这些继承类。抽象类仅在不同的继承类表示不同的对象但需要共享一组(几乎)通用方法时才有用。如果没有,请忘记“抽象”父级,只需设计满足您需要的类。
注意继承自 handle
类的类。在 Matlab 中,它们的行为与 value
类不同。阅读this article 并决定您想要哪种类型。
如果您决定使用handle
类,请考虑以下非常重要的因素Initialising property value:
将属性初始化为唯一值
MATLAB 仅将属性分配给指定的默认值一次 当 MATLAB 加载类定义时。因此,如果您初始化一个 具有句柄类构造函数的属性值,MATLAB 调用它 构造函数只有一次,每个实例都引用同一个句柄 目的。如果您希望将属性值初始化为新的 每次创建对象时,都分配句柄对象的实例 构造函数中的属性值。
现在考虑到所有这些,下面是您的类的一个可以运行的版本,您可以按如下方式进行实例化:
>> dl = DataLoader
dl =
DataLoader with no properties.
>> dl.getInfo
ans =
Import
>> dl.getStatus
ans =
-1
>> dl.LoadData(1,2,3) %// etc ...
类定义如下
classdef DataLoader < DataLoaderIF
properties (Access=protected)
mStatus %// nothing done
mInfo %//
mData %// saving the imported data
mCollector %// to save the prices after structuring
end
methods
%// Constructor (and initialise default value). For classes which
%// inherit from the "handle" class it is very important to
%// intialise your default values IN THE CONSTRUCTOR, and NOT in
%// the property definition.
function obj = DataLoader
obj.mStatus = -1 ;
obj.mInfo = 'Import' ;
obj.mData = [] ;
obj.mCollector = [] ;
end
function Status = getStatus(obj)
Status = obj.mStatus ;
end
function Info = getInfo(obj)
%// a "get" type of function should not assign value, only
%// return information about the object.
Info = obj.mInfo ;
end
%// the "obj" parameter has to be the first parameter of the
%// function in it's signature.
function LoadData(obj,Asset,Start,End)
%// Put function help here
%// I don't know what this part of the code is supposed to do
%// so I leave it as it is. Be aware that the fucntion "fetch"
%// will have to be accessible in your context or the function
%// will error
connection = 'yahoo' ;
obj.mData = fetch(connection, Asset, Start , End, 'd') ;
close(connection)
obj.mCollector= ['date' 'open' 'high' 'low' 'close' 'volume' 'adj-close'
cellstr(datestr(obj.mData(:,1))) num2cell(obj.mData(:,2:end))];
%// Here do your own test with your own conditions to decide
%// what the status of the object should be.
if ~isempty(obj.mData) && ~isempty(obj.mCollector)
obj.Status = 1 ;
end
end
end
end
您似乎对 OOP 的某些概念有些困惑。如果您第一次接触 OOP 是通过 Matlab,我完全理解您来自哪里。我有同样的经历,多年来我对 OOP 的理解一直是错误的(结果我的 OOP 代码非常糟糕且效率低下),直到我在 C++
和 .Net
正确地学习了我的方式。最后两种语言是真正的 OOP 语言(我知道,不是唯一的,或者更好的一种,我不想开始辩论),因为您需要了解 OOP概念来从中得到任何东西。另一方面,您可以在 Matlab 上度过一生,做一些美妙的事情,并且幸福地不知道 OOP 意味着什么。
Matlab 中引入了 OOP 功能,为那些错过了这种构建代码方式的程序员提供了一种“便利”。第一个实现非常笨重且不实用(如果您还记得必须为您的每一个代码编写代码,请举手subassign
、subsref
、display
、get
、set
等每个对象!!)。从那时起,它得到了极大的改进,直到现在,如果您想获得 OOP 组织的好处(代码重用、多态性、继承等),那么值得付出额外的编码努力。然而,直到今天,Matlab 中的 OOP 语法一开始即使对于 OOP 的老手来说仍然不是本能的(为什么我们必须将对象本身声明为函数的第一个参数,编译器是否如此盲目呢? '没有看到函数在类定义中?)。你只需要先习惯它,然后就可以了。
关于 OOP 的 Matlab 文档主要面向这些老手。它向了解另一种语言的 OOP 的人解释了如何在 Matlab 特定语法中应用这些概念。对于纯粹的初学者来说,这根本不是一个很好的指南。
这个(比我想要的更长,对不起)简介,是为了解释:
如果您需要学习 OOP 概念,请先用另一种语言训练自己。 (说真的,即使有学习另一种语言的学习曲线,与使用 Matlab 上的试错法相比,您花费的时间也会更少)。
如果您对 Matlab 中的 OOP 代码没有明确的需要,请不要坚持。您可以在 Matlab 中做很多事情(实际上几乎所有事情)而无需求助于类(至少在不知情的情况下,您当然会在后台使用基本的 Matlab 类,但是您可以使用和维护您的汽车多年而无需必须对其每个组件都有深入的了解)。
【讨论】:
谢谢!我刚回到家,现在我正在通过你的代码工作!已经非常感谢了。这对我有很大帮助!当我实现它并在您的帮助下取得进展时,我将更详细地回答您! 我刚刚实施了您的建议,并感谢您的工作。您找到了我正在寻找的东西并理解了我的问题。但不幸的是,我仍然有一些问题。我按照您的建议实现了,但我收到以下错误消息:Undefined function or variable 'DataLoader'.
该程序应该是可扩展的,因此需要 OOP。我将获得一些 C++ 书籍来提高我的技能,但是时间很短,所以我希望已经使用 Matlab 进行改进。我使用了与here 相同的符号
我不能写超过 600 个字符,所以这里是其余的答案!我已经在寻找文献并找到了两本很有前途的书,我的问题中提到的一本,但是它们没有处理面向对象的编程和抽象类。带有句柄的提示以及在哪里启动值真的很有帮助,不知道!真正奇怪的是,在执行完代码后我得到了一个对象,但这被称为 ans 而不是 obj。如何更改结果对象的名称?
您的对象将由您在第一次实例化它时使用的变量名调用(第一次调用构造函数时)。因此,如果您键入dl = DataLoader
,您的工作区中将有一个名为dl
的对象实例。如果你调用构造函数而不给它一个名字(就像简单的DataLoader
),Matlab 将分配在默认变量中返回的对象,总是称为ans
。 (ans
是 answer
的缩写)。如果您没有指定结果变量,ans
将始终用于在控制台中存储最后一次操作的结果(尝试在控制台中键入 2+3
...)
您好 Hoki,再次感谢您帮助我。昨天没看你的帖子,现在才看到。很抱歉耽搁了。我必须给我的函数一个返回变量是有意义的,并且与我在 Java 中学到的相似。但是当我尝试运行 dl = DataLoader 他告诉我'未定义的函数或变量DataLoader'
。我不明白,因为通常他应该知道这个变量,因为它是我的 classdef
的名称,还是我遗漏了什么?我按照您的建议实现了代码,但总是收到此错误消息...已经将其添加到路径中...以上是关于Matlab - 具有抽象接口的面向对象 - 如何创建对象?的主要内容,如果未能解决你的问题,请参考以下文章