Załóżmy, że mam obiekt X
klasy MyClass
. MyClass
ma metodę compute
, a gdy zadzwonię pod numer U = compute(X,...)
, program matlab automatycznie wywoła metodę klasy. Jednak tak naprawdę chcę wywołać inną funkcję o nazwie compute
, której parametry zaczynają się od obiektu MyClass
. Jak zmusić matlab do wywoływania tej zwykłej funkcji, a nie do metody klasowej?Jak zmusić matlab do wywoływania zwykłej funkcji, a nie metody klasy, gdy są przeciążone?
Odpowiedz
Nie można tego zrobić bez wprowadzania pewnych zmian w nazwie lub lokalizacji funkcji. W przypadku sprawdzania Matlab's function precedence order metody zawsze działają przed normalnymi funkcjami zewnętrznymi. Twoje jedyne praktyczne opcje to:
- Zmień nazwę funkcji.
- Przesuń ciało funkcja do tego samego skryptu, który jest wywołanie funkcji (punkt 4 na liście powyżej)
- Przenieś plik .m z funkcji w folderze o nazwie
private
w tym samym folderze co plik skryptu (pozycja 5 na lista)
UPDATE
Chociaż nie bardzo praktyczne dla mniejszych projektów, można również zajrzeć do packaging your functions. Dobrą dyskusję można znaleźć w this SO post.
Problem polega na tym, że nawet ja zmieniam nazwę funkcji na ' compute2', matlab nadal próbuje wywołać metodę klasy i zakończył zgłaszanie błędu, ponieważ 'compute2' nie jest zdefiniowany w' MyClass' ... – OneZero
w rzeczywistości, jeśli zmieniono nazwę zwykłej funkcji na "compute2", to zostanie ona nazwana poprawnie (I po prostu wypróbowałem to w R2013a) – Amro
@OneZero Pamiętaj, że musisz zmienić zarówno nazwę funkcji, jak i nazwę pliku zawierającego tę funkcję. Na przykład skończysz z 'function x = compute2 (obj)' wewnątrz pliku 'compute2.m'. – Bee
Jeśli Twój compute
dzieje się wbudowane MATLAB, można użyć
builtin('compute', ...)
inaczej, nie ma mowy - patrz odpowiedź Bee.
Dobra uwaga. Właśnie założyłem, ponieważ jego funkcja "compute" akceptuje obiekt niestandardowy jako pierwszy parametr, nie jest to funkcja wbudowana. – Bee
@Bee: true. Najprawdopodobniej OP nie zajmuje się wbudowanym. Ale ktoś inny mógłby: p –
Jeśli bardzo tego potrzebujesz, możesz zrobić coś takiego. Zdecydowanie sugeruję, abyś tego nie robił i trzymaj się odpowiedzi Bee. Jednak czasami nie ma się wyboru ...
Chodzi o to, aby owinąć instancję w inną klasę, aby funkcja wysyłania funkcji MATLAB nie widziała metody compute
. Jednak do funkcji compute
, opakowana instancja musi wyglądać tak samo jak oryginalna instancja. Jest to trudne, aby uzyskać prawo w niektórych przypadkach, ale często po to wystarczy:
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
Ta klasa jest zawijany wystąpienie innej klasy i delegatów wszystkim dostęp do odczytu zawiniętego instancji.
Na przykład, jeśli masz plik o nazwie 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
i funkcję compute.m
:
function compute(x)
fprintf('Regular function! My name is "%s".\n', x.name);
end
Wtedy to działa tak:
>> 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".
W zależności od tego, co funkcja compute
działa z Twoją instancją Trzeba dodać dodatkowe "specjalne" funkcje do Wrapper
(np. subsasgn
). Zauważ, że to się zepsuje, jeśli compute
zrobi magię metaklasu.
dowolny powód, dlaczego obie wersje nie są metodami członków? możesz również uczynić funkcję zewnętrzną statyczną metodą klasy, w ten sposób nazywa się ją inaczej: 'MyClass.compute (x)' kontra 'compute (x)' – Amro