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?
Antwort
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:
- Ändern Sie den Namen der Funktion.
- die körpereigene Funktion auf das gleiche Skript verschieben, die die Funktion (Punkt 4 auf der Liste oben) rufen
- 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.
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
Wenn Sie die reguläre Funktion als 'compute2' umbenannt haben, wird sie korrekt aufgerufen (I gerade versucht es in R2013a) – Amro
@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
Wenn Ihr compute
ein MATLAB builtin passiert sein, können Sie
builtin('compute', ...)
verwenden sonst, gibt es keine Möglichkeit - siehe Bee Antwort.
Guter Punkt. Ich habe gerade angenommen, da seine 'compute' -Funktion das benutzerdefinierte Objekt als ersten Parameter akzeptiert, ist es keine eingebaute Funktion. – Bee
@Bee: wahr. Aller Wahrscheinlichkeit nach handelt es sich bei dem OP nicht um ein eingebautes System. Aber jemand anderes könnte: p –
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.
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