【问题标题】:Matlab: Find All Objects of Specific Classes and Pass to FunctionMatlab:查找特定类的所有对象并传递给函数
【发布时间】:2018-04-24 12:42:15
【问题描述】:

我是面向对象编程的新手。假设我有几个不同类的对象:

福特(类别:汽车)

大众(类别:汽车)

猫(类:动物)

波音(类:飞机)

现在我想在 car 和 plane 的每个对象上运行一个函数 calculateSpeed。我知道我必须遍历所有工作区变量,识别所寻找的对象并将它们传递给我的函数:

myvars = whos;
for i = 1:numel(myvars)
    if isa(myvars(i),'car') | isa(myvars(i),'plane')
       calculateSpeed(myvars(i));
    end
end

显然它不起作用,因为我没有将实际对象传递给函数,而只是将myvars 中的对象引用传递给函数。如何在特定对象上巧妙地运行函数?

更新(见 cmets):

我的 classdef 文件 car.m 如下所示:

classdef car  
    properties
        a;
        e;
        i;
    end    
    methods      
    end
end

我的函数 calculateSpeed 如下所示:

function [ speedArray ] = calculateSpeed(object)
T = 2 * pi() * sqrt(object.a^3);
[...]
end

Matlab 给了我错误 Reference to non-existent field 'a'. 我假设,因为该函数不是使用实际对象操作,而是使用由 whos 创建的结构。

【问题讨论】:

    标签: matlab oop


    【解决方案1】:

    实际上,循环遍历所有工作区变量并不是最佳做法。如果您的工作区包含大量变量,并且其中大多数变量对于您的计算来说不是必需的,那么您将无缘无故地花费大量时间来完成这项任务。

    您必须在代码中分配/实例化这些类的时刻,这将是将它们插入到包含不同现有对象类别的不同单元数组中的好时机。这样,您只需将代码应用于目标元胞数组中的所有实例即可获得所需的结果。

    另一个好主意是创建一个名为Vehicle 的超类,Car 和“Plane”类都将继承。然后,您可以将您的函数calculateSpeed 定义到超类中,这样您就可以继续处理通用类配置文件并避免检查许多不同类型的类。但是,如果您坚持使用循环工作区变量,这将很棘手。

    带有工作区变量的选项 1:

    % Animal Categories
    
    classdef Animal < handle 
        % ...
    end
    
    % Vehicle Categories
    
    classdef (Abstract) Vehicle < handle
        properties
            Speed
        end
    
        methods
           function CalculateSpeed(this)
               this.Speed = 100; % your calculations here
           end
        end
    end
    
    classdef Car < Vehicle
        % ...
    end
    
    classdef Plane < Vehicle
        % ...
    end
    
    % Script Code
    
    Ford = Car();
    VW = Car();
    Boeing = Plane();
    car = Animal();
    
    vars = whos();
    
    for i = 1:numel(vars)
        var_curr = vars(i);
    
        if (strcmp(var_curr.class,'Car') || strcmp(var_curr.class,'Plane'))
            eval([var_curr.name '.CalculateSpeed()']);
        end
    end
    

    完全控制实例分配的选项 2:

    % Animal
    
    classdef (Abstract) Animal < handle
        % ...
    end
    
    % Vehicle
    
    classdef Vehicle < handle
        properties
            Name
            Speed
            Type
        end
    
        methods
            function this = Vehicle(type,name)
                this.Type = type;
                this.Name = name;
                this.CalculateSpeed();
            end
        end
    
        methods
           function CalculateSpeed(this)
               switch (this.Type)
                    case 'Car' 
                        this.Speed = 50;
                    case 'Plane'
                        this.Speed = 150;
                    otherwise
                       this.Speed = 0;
               end
           end
        end
    end
    
    % Script Code
    
    insts = cell(10,1);
    
    for i = 1:10
        insts{i} = Vehicle(type,name);
    end
    

    如果您不想在实例化对象时直接计算速度,那么只需在构造函数中注释对方法的调用,并在必要时运行循环来执行此操作:

    for i = 1:10
        insts{i}.CalculateSpeed();
    end
    

    选项 3,让我们继续使用您的想法:

    vars = whos();
    
    for i = 1:numel(vars)
        var_curr = vars(i);
    
        if (strcmp(var_curr.class,'Car') || strcmp(var_curr.class,'Plane'))
            s = eval(['calculateSpeed(' var_curr.name ')']);
        end
    end
    

    附带说明,if 条件中的逻辑运算符必须是双精度的。单个逻辑运算符只能在索引上下文中的两个逻辑运算符之间使用。此外,请始终尝试缓存您的索引结果,因为 Matlab 中的 for 循环很昂贵,这可以在大循环中节省大量时间。

    【讨论】:

    • 看看你如何定义你的类可能会有所帮助。无论如何,我会编辑我的答案,试图澄清你的疑问
    猜你喜欢
    • 2021-12-24
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 2014-06-04
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    相关资源
    最近更新 更多