2012-08-08 20 views
9

viết một lớp con của dynamicprops cho phép tôi để thêm các thuộc tính tự động đến một đối tượng:là nó có thể thêm phương pháp trên bay đến lớp MATLAB (lập trình hướng đối tượng)?

addprop(obj, 'new_prop') 

này là rất tốt, nhưng tôi cũng rất thích tạo set/get chức năng đối với những tài sản trên khi đang bay. Hoặc các hàm phân tích hoạt động trên các thuộc tính động này.

Kinh nghiệm của tôi với Matlab đã được cho đến nay, rằng khi tôi tạo ra một thể hiện của một lớp, thêm phương pháp mới là không thể. Điều đó rất cồng kềnh, bởi vì đối tượng của tôi có thể chứa rất nhiều dữ liệu, tôi sẽ phải tải lại mọi lúc mà tôi muốn thêm một phương thức mới (vì tôi phải làm clear classes).

Vậy có cách nào để thêm phương thức khi đang di chuyển không?

+0

Bạn có thể thêm các phương thức mới miễn là bạn thực hiện các lớp rõ ràng sau đó, nhưng bạn muốn thực hiện nó. Tôi không nghĩ rằng sẽ làm việc nói chung. –

Trả lời

10

Bạn không thể thêm các phương pháp như bạn thêm thuộc tính động. Tuy nhiên, có hai cách để triển khai các phương thức mới trong quá trình phát triển mà không yêu cầu bạn phải tải lại dữ liệu mỗi lần.

(1) Tôi viết các phương thức chuẩn làm các hàm riêng biệt và gọi chúng là myMethod(obj) trong quá trình phát triển. Khi tôi chắc chắn rằng chúng ổn định, tôi thêm chữ ký của chúng vào tệp định nghĩa lớp - điều này yêu cầu một số clear classes, tất nhiên, nhưng nó bị trì hoãn nhiều và thỉnh thoảng bạn có thể phải tắt Matlab, .

(2) Với phương thức thiết lập/nhận, mọi thứ trở nên phức tạp hơn một chút. Nếu bạn đang sử dụng các thuộc tính mới dynamicprops để thêm thuộc tính mới, bạn cũng có thể chỉ định phương thức đặt/nhận của họ (rất có thể, các phương pháp/chức năng này sẽ muốn nhận tên của thuộc tính để họ biết phải tham khảo):

addprop(obj,'new_prop'); 
prop = findprop(obj,'new_prop'); 
prop.SetMethod = @(obj,val)yourCustomSetMethod(obj,val,'new_prop') 

EDIT

(2,1) Dưới đây là một ví dụ về cách thiết lập thuộc tính ẩn để lưu trữ và lấy kết quả (dựa trên jmlopez' answer). Rõ ràng điều này có thể được cải thiện rất nhiều nếu bạn có ý tưởng tốt hơn về những gì bạn đang thực sự thiết kế

classdef myDynamicClass < dynamicprops 
    properties (Hidden) 
     name %# class name 
     store %# structure that stores the values of the dynamic properties 
    end 
    methods 
     function self = myDynamicClass(clsname, varargin) 
      % self = myDynamicClass(clsname, propname, type) 
      % here type is a handle to a basic datatype. 
      self.name_ = clsname; 
      for i=1:2:length(varargin) 
       key = varargin{i}; 
       addprop(self, key); 
       prop = findprop(self, key); 
       prop.SetMethod = @(obj,val)myDynamicClass.setMethod(obj,val,key); 
       prop.GetMethod = @(obj)myDynamicClass.getMethod(obj,key); 
      end 
     end 
     function out = classname(self) 
      out = self.name_; 
     end 
    end 
    methods (Static, Hidden) %# you may want to put these in a separate fcn instead 
     function setMethod(self,val,key) 
      %# have a generic test, for example, force nonempty double 
      validateattributes(val,{'double'},{'nonempty'}); %# will error if not double or if empty 

      %# store 
      self.store.(key) = val; 

     end 
     function val = getMethod(self,key) 
      %# check whether the property exists already, return NaN otherwise 
      %# could also use this to load from file if the data is not supposed to be loaded on construction 
      if isfield(self.store,key) 
       val = self.store.(key); 
      else 
       val = NaN; 
      end 
     end 
    end 
end 
+0

vì vậy 'myMethod' sẽ thực sự là một hàm chung (và không phải là một phương thức lớp) mà bạn có thể thay đổi theo ý muốn, phải không? – memyself

+1

@memyself: chính xác. Sau đó, bạn có thể sao chép 'myMethod' vào tệp classdef hoặc chỉ cần thêm chữ ký vào tệp classdef và di chuyển' myMethod' vào thư mục lớp. – Jonas

+0

đó là một mẹo nhỏ gọn - tôi chưa bao giờ nghĩ về nó! – memyself

3

Tôi thêm câu trả lời này bởi vì tôi nghĩ rằng điều này không trực quan. Ít nhất là không cho bản thân mình vào lúc này. Sau khi tìm thấy câu hỏi này, tôi nghĩ rằng tôi đã có những gì tôi cần để có thể xác định các phương thức set/get cho lớp động của tôi. Tất cả tôi muốn đạt được với điều này là một cái gì đó tương tự như những gì python hiện với phương pháp __setattr__ của nó. Trong mọi trường hợp, đây là một continuation của lớp được thực hiện bởi @jonas một thời gian trước đây với một vài sửa đổi để thêm phương thức đặt tùy chỉnh của chúng tôi.

classdef myDynamicClass < dynamicprops 
    properties (Hidden) 
     name_ %# class name 
    end 
    methods 
     function self = myDynamicClass(clsname, varargin) 
      % self = myDynamicClass(clsname, propname, type) 
      % here type is a handle to a basic datatype. 
      self.name_ = clsname; 
      for i=1:2:length(varargin) 
       key = varargin{i}; 
       addprop(self, key); 
       prop = findprop(self, key); 
       prop.SetMethod = makefunc(key, varargin{i+1}); 
      end 
     end 
     function out = classname(self) 
      out = self.name_; 
     end 
    end 
end 

function h = makefunc(key, argtype) 
    h = @newfunc; 
    function newfunc(obj, val) 
     obj.(key) = argtype(val); 
    end 
end 

Với lớp này, tôi xác định phương pháp đã đặt để tham số được chuyển đến thuộc tính được sao chép sang đúng loại. Để xem những gì tôi có nghĩa là xem xét việc sử dụng sau đây:

>> p_int = myDynamicClass('Point', 'x', @int8, 'y', @int32); 
>> p_int.x = 1000 

p_int = 

    myDynamicClass with properties: 

    y: [] 
    x: 127 

>> class(p_int.x) 

ans = 

int8 

Với điều này, chúng tôi đã buộc các thuộc tính x là một số nguyên 8 bit mà chỉ có thể giữ nguyên từ -128 đến 127. Cũng cần chú ý cách lớp của mỗi thuộc tính cho chúng ta loại dự định.

+1

Điều này là chính xác. Lưu ý rằng khi xác định các phương thức set/get tùy chỉnh, bạn có thể gặp rủi ro về việc thu thập vô hạn, vì trình phân tích cú pháp Matlab sẽ không luôn biết tránh gọi phương thức set khi bạn gán giá trị của thuộc tính. Để làm cho cuộc sống của bạn dễ dàng hơn (cũng cho mục đích gỡ lỗi), có thể hữu ích khi có một thuộc tính ẩn để lưu trữ các giá trị, sau đó được truy cập bằng các phương thức getter/setter. – Jonas

+1

@Jasas nhận xét tuyệt vời - bạn có thể xây dựng thêm một chút về thuộc tính ẩn và cách triển khai tính năng này không? – memyself

+0

@ Jason, do đó, tương tự như python '__dict__' biến. Họ đề cập đến khả năng đệ quy vô hạn [ở đây] (http://docs.python.org/2/reference/datamodel.html#object.__setattr__). Có một số tài liệu về MATLAB giải thích làm thế nào để làm điều này? – jmlopez

Các vấn đề liên quan