Why won't my superclass method change my subclass object?

4 vues (au cours des 30 derniers jours)
Captain Karnage
Captain Karnage le 26 Août 2022
Commenté : Captain Karnage le 26 Août 2022
I am trying superclass / subclass relationships for the first time. I have defined a subclass, M, with two super classes, S & R. My subclass has data in it and I want to call a superclass method from each superclass to add data to the subclass.
When I call the superclass method, it is called and executes correctly on the subclass object. However, when it returns from the call, the subclass object remains unchanged. I'm sure it's something obvious I'm missing but I've searched the forums and can't quite seem to find what I'm looking for.
I created the following files as a generic example that illustrates what I'm seeing:
M.m:
classdef M < S & R
%M Summary of this class goes here
% Detailed explanation goes here
properties
data
end
methods
function obj = M(a, b, c)
%M Construct an instance of this class
% Detailed explanation goes here
obj@S(a,b);
obj@R(a,c);
obj.data = repmat([b c], a, 1);
disp('Original M Object:');
disp(obj);
disp(obj.data);
obj.addSdata;
disp('M Object after calling S Method:');
disp(obj);
disp(obj.data);
disp('M object after calling R Method:');
obj.addRdata;
disp(obj);
disp(obj.data);
end
end
end
S.m:
classdef S
%S Summary of this class goes here
% Detailed explanation goes here
properties (Constant)
Sdivisor = 3;
end
properties (Abstract)
data
end
properties (Access = private)
a
b
end
methods
function obj = S(Sa, Sb)
%S Construct an instance of this class
% Detailed explanation goes here
obj.a = Sa;
obj.b = Sb;
end
function obj = addSdata(obj)
%METHOD1 Summary of this method goes here
% Detailed explanation goes here
newb = obj.b / obj.Sdivisor;
newcol = repmat(newb, obj.a, 1);
obj.data = [obj.data newcol];
disp('Object in S Workspace:');
disp(obj);
disp(obj.data);
end
end
end
R.m:
classdef R
%R Summary of this class goes here
% Detailed explanation goes here
properties (Constant)
Rmultiplier = 3;
end
properties (Abstract)
data
end
properties (Access = private)
a
c
end
methods
function obj = R(Ra, Rc)
%R Construct an instance of this class
% Detailed explanation goes here
obj.a = Ra;
obj.c = Rc;
end
function obj = addRdata(obj)
%METHOD1 Summary of this method goes here
% Detailed explanation goes here
newc = obj.Rmultiplier * obj.c;
newcol = repmat(newc, obj.a, 1);
obj.data = [obj.data newcol];
disp('Object in R Workspace:');
disp(obj);
disp(obj.data);
end
end
end
testM.m:
Mo = M(10,102,100);
Output:
>> TestM
Original M Object:
M with properties:
data: [10×2 double]
Sdivisor: 3
Rmultiplier: 3
102 100
102 100
102 100
102 100
102 100
102 100
102 100
102 100
102 100
102 100
Object in S Workspace:
M with properties:
data: [10×3 double]
Sdivisor: 3
Rmultiplier: 3
102 100 34
102 100 34
102 100 34
102 100 34
102 100 34
102 100 34
102 100 34
102 100 34
102 100 34
102 100 34
M Object after calling S Method:
M with properties:
data: [10×2 double]
Sdivisor: 3
Rmultiplier: 3
102 100
102 100
102 100
102 100
102 100
102 100
102 100
102 100
102 100
102 100
M object after calling R Method:
Object in R Workspace:
M with properties:
data: [10×3 double]
Sdivisor: 3
Rmultiplier: 3
102 100 300
102 100 300
102 100 300
102 100 300
102 100 300
102 100 300
102 100 300
102 100 300
102 100 300
102 100 300
M with properties:
data: [10×2 double]
Sdivisor: 3
Rmultiplier: 3
102 100
102 100
102 100
102 100
102 100
102 100
102 100
102 100
102 100
102 100
As you can see, it creates the object correctly and sets up the initial data. Further, when I call the superclass methods, it uses the subclass object, M, and changes it as expected while it is running. So up to that point, it runs as I'm expecting.
Once it exits the method, however, the subclass object returns to its original state. This happens for both superclass methods.
What do I need to change to get this to work the way I want?
  1 commentaire
Captain Karnage
Captain Karnage le 26 Août 2022
Modifié(e) : Captain Karnage le 26 Août 2022
I also tried declaring the methods "addRdata" and "addSdata" in M.m as follows:
function obj = addRdata(obj)
addRdata@R(obj);
end
function obj = addSdata(obj)
addSdata@S(obj);
end
and got the exact same result.

Connectez-vous pour commenter.

Réponse acceptée

Matt J
Matt J le 26 Août 2022
Modifié(e) : Matt J le 26 Août 2022
You need,
obj=obj.addSdata;
obj=obj.addRdata;
Or, read about handle classes.
  3 commentaires
Matt J
Matt J le 26 Août 2022
I guess I assumed that anything passing the class object to an internal method that changes the object would change the object without obj =
Well, that is indeed the case for a handle class (see my earlier link), so you might consider inheriting from handle as well, if you truly need that behavior.
Captain Karnage
Captain Karnage le 26 Août 2022
I'll definitely be looking into handle objects, thank you. For now, I have it working with that simple change.
Also... as a note in case anyone else ever has a similar issue. This solution worked immediately on the example code I provided. When I put it into my real program, it didn't seem to work at first, I was getting the same result. Then I realized I left in the subclass methods using the @ reference to the superclass and those didn't have the obj = on them, either. So if anyone copied from that comment, just remove those subclass methods.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Construct and Work with Object Arrays dans Help Center et File Exchange

Produits


Version

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by