2013-07-10 23 views
5

Angenommen, ich habe ein Objekt X der Klasse MyClass. MyClass hat eine Methode compute, und wenn ich U = compute(X,...) aufrufen, ruft Matlab automatisch die Klassenmethode auf. Was ich eigentlich will, ist eine andere Funktion namens compute aufzurufen, deren Parameter jedoch mit einem MyClass Objekt beginnen. Wie erzwinge ich Matlab, diese reguläre Funktion aufzurufen, anstatt in die Klassenmethode zu gehen?Wie erzwinge ich, dass Matlab eine reguläre Funktion anstatt einer Klassenmethode aufruft, wenn sie überlastet sind?

+1

Warum sind beide Versionen keine Mitgliedsmethoden? Sie könnten auch die externe Funktion zu einer statischen Methode der Klasse machen, so dass sie anders heißt: 'MyClass.compute (x)' vs. 'compute (x)' – Amro

Antwort

6

Es gibt keine Möglichkeit, dies zu tun, ohne den Namen oder den Standort der Funktion zu ändern. Wenn Sie Matlab's function precedence order überprüfen, werden Methoden immer vor normalen externen Funktionen ausgeführt. Ihre einzigen praktischen Optionen sind:

  1. Ändern Sie den Namen der Funktion.
  2. die körpereigene Funktion auf das gleiche Skript verschieben, die die Funktion (Punkt 4 auf der Liste oben) rufen
  3. die .m-Datei auf einen private im selben Ordner wie die Skriptdatei (Punkt 5 genannt Ordner Funktion Move on die folgende Liste)

UPDATE

Obwohl nicht ganz praktisch für kleinere Projekte haben, können Sie auch in packaging your functions suchen. Eine gute Diskussion findet sich in this SO post.

+0

Das Problem ist, sogar ich ändere den Funktionsnamen in ' compute2', versucht Matlab immer noch, die Klassenmethode aufzurufen, und hat einen Fehler gemeldet, da 'compute2' nicht in' MyClass' definiert ist ... – OneZero

+0

Wenn Sie die reguläre Funktion als 'compute2' umbenannt haben, wird sie korrekt aufgerufen (I gerade versucht es in R2013a) – Amro

+0

@OneZero Denken Sie daran, dass Sie sowohl den Funktionsnamen und den Dateinamen mit dieser Funktion ändern müssen. Zum Beispiel werden Sie am Ende mit 'Funktion x = compute2 (obj)' in der Datei 'compute2.m' enden. – Bee

2

Wenn Ihr compute ein MATLAB builtin passiert sein, können Sie

builtin('compute', ...) 

verwenden sonst, gibt es keine Möglichkeit - siehe Bee Antwort.

+0

Guter Punkt. Ich habe gerade angenommen, da seine 'compute' -Funktion das benutzerdefinierte Objekt als ersten Parameter akzeptiert, ist es keine eingebaute Funktion. – Bee

+1

@Bee: wahr. Aller Wahrscheinlichkeit nach handelt es sich bei dem OP nicht um ein eingebautes System. Aber jemand anderes könnte: p –

2

Wenn Sie dies dringend benötigen, können Sie etwas wie folgt tun. Ich schlage vor, dass Sie das nicht tun und bei Bees Antwort bleiben. Manchmal hat man jedoch keine andere Wahl ...

Die Idee besteht darin, Ihre Instanz in eine andere Klasse zu verpacken, so dass MATLABs Funktionsverteilung die Methode compute nicht sehen kann. Für Ihre Funktion compute muss die umbrochene Instanz jedoch genauso aussehen wie die ursprüngliche Instanz. Das ist heikel Recht in einigen Fällen zu bekommen, aber oft ist folgendes genug:

classdef Wrapper 

    properties (Access = 'private', Hidden = true) 
     core = []; 
    end 

    methods 

     function this = Wrapper(core) 
      this.core = core; 
     end 

     function varargout = subsref(this, S) 
      if nargout > 0 
       varargout = cell(1, nargout); 
       [varargout{:}] = subsref(this.core, S); 
      else 
       subsref(this.core, S); 
      end 
     end 

    end 

end 

Diese Klasse wickelt eine Instanz einer anderen Klasse und die Delegierten alle Zugriff auf die umhüllte Instanz lesen.

Zum Beispiel, wenn Sie eine Datei namens TestClass.m:

classdef TestClass 

    properties 
     name = ''; 
    end 

    methods 
     function this = TestClass(name) 
      this.name = name; 
     end 

     function compute(this) 
      fprintf('Instance method! My name is "%s".\n', this.name); 
     end 
    end 

end 

und eine Funktion compute.m:

function compute(x) 
    fprintf('Regular function! My name is "%s".\n', x.name); 
end 

Dann funktioniert es dies wie:

>> t = TestClass('t'); 
>> s = struct('name', 's'); 
>> compute(t) 
Instance method! My name is "t". 
>> compute(s) 
Regular function! My name is "s". 
>> w = Wrapper(t); 
>> compute(w) 
Regular function! My name is "t". 

Je nachdem, was Die compute Funktion macht mit deiner Instanz du mi ght muss weitere "spezielle" Funktionen zu Wrapper hinzufügen (z.B. subsasgn). Beachten Sie auch, dass dies bricht, wenn compute einige Metaklassen-Magie tut.

+0

+1. Gute Ermittlungsarbeit! – Bee

+0

die letzte 'doStuff (w)' sollte 'compute (w)' sein. +1 für die Problemumgehung, aber ich empfehle auch nicht, dies in echtem Code zu verwenden :) – Amro

+0

@Amro: Danke, behoben. Das war von meinem Trial-and-Error-Code übrig geblieben. –