Can a child object reference to a parent object?

조회 수: 13 (최근 30일)
Youssef
Youssef 2015년 1월 18일
편집: Guillaume 2015년 1월 19일
1 object (or instance) of a certain class can reference to another previously declared one if the the class had the "< handle" right at the beginning of its definition. If I defined a child class and declared a child object, can this object reference to a certain parent object? I mean if A is property in the parent class, can I by changing this property in the child class object (or instance) change it automatically in the parent class object (or instance) if they both reference to each other? I'm not sure whether the "class" function class(s,'class_name',parent); would had done the job, but it's now obsolete anyway. There must be a way. Thanks for helping.

답변 (3개)

per isakson
per isakson 2015년 1월 18일
편집: per isakson 2015년 1월 18일
Here is one way to let parent and child share a variable.
pc = ParentClass;
cc = ChildClass;
cc.A.a = 17;
pc.A.a
pc.A.a = 18;
cc.A.a
shows in the command window
ans =
17
ans =
18
where
classdef ParentClass < handle
properties
A = DataStore;
end
end
classdef ChildClass < ParentClass
end
classdef DataStore < handle
properties
a
end
end
&nbsp
However, I doubt ...
  댓글 수: 1
Youssef
Youssef 2015년 1월 19일
Actually DataStore a property can change by any instance (I mean it has a global scope) whether it was a ParentClass object or even another object of ParentClass! Funny behavior and I can't explain it, like if this is a new way to make something like a global variable?

댓글을 달려면 로그인하십시오.


Guillaume
Guillaume 2015년 1월 19일
편집: Guillaume 2015년 1월 19일
Actually, I think it's possible to do what you want as long as the base class is a handle class.
First, a note of terminology, parent/child are not the terms traditionally used to describe inheritance. Matlab uses superclass/subclass and most everybody else uses base/derived.
If I've understood correctly, what you want to do is given an object of the base class (let's call it a), you want to create an object of the derived class (let's call it b) that is linked to a. Any change to the properties of a are reflected in b and any change to the properties of b derived from the base class are reflected in a.
I'm not sure it's a good idea, but it's doable in matlab, using dynamic properties. Note that the derived class doesn't actually derive from the base class:
classdef base < handle %base has to be a handle class
properties
someprop;
someotherprop;
end
end
classdef derived < dynamicprops & handle
%doesn't have to derive from handle if you don't want
%doesn't derive from base, inheritance implemented through dynamic props
properties
somemoreprop;
end
properties (Access = private)
baseref; %reference to base object
end
methods
function this = derived(baseobject)
validateattributes(baseobject, {'base'}, {'scalar'});
this.baseref = baseobject;
%now 'inherit' all the properties of the base object:
for propname = properties(baseobject)'
metaprop = addprop(this, propname{1});
metaprop.SetMethod = @(this, varargin) SetDispatch(this, propname{1}, varargin{:});
metaprop.GetMethod = @(this) GetDispatch(this, propname{1});
end
end
end
methods (Access = private)
function SetDispatch(this, propname, varargin)
%called whenever a dynamic property is set.
%just dispatch to the figure property
this.baseref.(propname) = varargin{:};
end
function varargout = GetDispatch(this, propname)
%called whenever a dependent dynamic property is read.
%just dispatch to the figure property
varargout{:} = this.baseref.(propname);
end
end
end
Usage example:
>> a = base; a.someprop = 45; a.someotherprop = [1 2 3]
a =
base with properties:
someprop: 45
someotherprop: [1 2 3]
>> b = derived(a); b.somemoreprop = {4 5 6}
b =
derived with properties:
somemoreprop: {[4] [5] [6]}
someotherprop: [1 2 3]
someprop: 45
>> a.someprop = -12; b
b =
derived with properties:
somemoreprop: {[4] [5] [6]}
someotherprop: [1 2 3]
someprop: -12
>>b.someotherprop = [0 0 0 0 0]; a
a =
base with properties:
someprop: -12
someotherprop: [0 0 0 0 0]
See also this answer where I developed the idea.
  댓글 수: 2
Youssef
Youssef 2015년 1월 19일
Thank you for your answer, I haven't run the code yet, just checking your output:
b = derived(a); b.somemoreprop = {4 5 6}
b =
derived with properties:
somemoreprop: []
someotherprop: [1 2 3]
someprop: 45
Why somemoreprop is still empty? It should be now {4 5 6}, right?
Another thing:
In the last command, I thought a.someprop would still be -12?!
Your code is new to me (I mean the dynamic concept). I will investigate it.
Guillaume
Guillaume 2015년 1월 19일
That's what you get for me paraphrasing the command line instead of copy-pasting the output. I can assure you it all work as expected.
I'm amending the post to correct these typos.

댓글을 달려면 로그인하십시오.


Youssef
Youssef 2015년 1월 19일
This is my answer to my own question: My answer is NO. (If you know otherwise please leave an answer in comments)
EXPLAINING THE SITUATION:
Having a class with some properties defined (a, b, and c for example) and some methods, we want to have - in a simple quick and easily readable manner - a class that inherits the properties and methods of that class - without them being explicitly redefined or rewritten again - and adds some own properties and methods such that the child object (instance) references to the parent object and vice versa (we don't care about static non-instantiated methods or properties) in the sense that changing a common (an inherited) property from within the child object would be the same as changing it from within the parent and that changing it from either place would imply a one same effect on memory.
REASONS TO POST THIS:
It took me a long time to find half a solution. That's the reason I'm posting here. As usual, I tried many times but no use and I searched on google hoping to find a quick easy answer but I didn't.
I'm adding a code to a large program where there is a class widely used. I need to add properties (a lot of them) to this class just for the purpose of my own additional code and it's against comprehensibility to add them in that class, so I thought of inheritance and I need them to reference one another.
FAILED PROCEDURE:
Firstly, in our case it's obvious that the parent class should derive from the handle built-in class. Unfortunately this didn't help. Suppose class1 is a parent class with properties a, b, and c. Let aa be an object of class1. Similarly, suppose class2 is a child class and let bb be an object of class2. Setting for example aa.a=9 does not set bb.a to any value.
Trying another method, I thought this "class" function might help as a built-in functionality; its syntax is
obj=class(s,'class_name',parent_class_object); % I put struct(parent_class_object) instead of s
It turned out that this function is obsolete since version 7.6 of Matlab, so I had to figure out something on my own.
After a very long time of thinking I saw this idea somewhere on the internet: The circular reference.
MY SOLUTION:
Our target lets us think that class2 should be structured (or made) this way: the class1 part (which - after instantiating an object of class2- should reference to an instance of class1 ) and the dedicated part of class2.
My approach was similar but not the same:
class2 is written the way we used to do usually.
Add a cl2 property in class1 that will reference to the class1 particular object.
Define an extra method in class1 to do the previous point.
Rely on set and get methods - in class2 only - to manage the parent and the child instances.
classdef class2<class1
properties
d
end
methods
...
end
end
classdef class1<handle
properties
a
b
c
end
methods
function refertochild(obj, c2)
obj.cl2=c2;
obj.cl2.a=obj.a; %it's important to directly set the values of the derivative object properties
obj.cl2.b=obj.b;
obj.cl2.c=obj.c;
end
function obj = set.a(obj,value)
obj.a = value;
if ~isempty(obj.cl2)
obj.cl2.a=value;
end
end
function obj = set.b(obj,value)
obj.b = value;
if ~isempty(obj.cl2)
obj.cl2.b=value;
end
end
function obj = set.c(obj,value)
obj.c = value;
if ~isempty(obj.cl2)
obj.cl2.c=value;
end
end
function value = get.a(obj)
value=obj.a;
if ~isempty(obj.cl2)
value=obj.cl2.a;
end
end
function value = get.b(obj)
value=obj.b;
if ~isempty(obj.cl2)
value=obj.cl2.b;
end
end
function value = get.c(obj)
value=obj.c;
if ~isempty(obj.cl2)
value=obj.cl2.c;
end
end
...
end
end
Directly after we initialize the child object bb in a certain script, the method refertochild must be directly called just once per lifetime like this:
aa.refertochild(bb);
If the parent object property aa is set the set method is triggered and the child object bb property will be then set, but the weakness is that if bb.c for example is set then aa.c won't be set until there is a request to get this property (c in this example) somewhere.
You can, if you prefer, put the content of refertochild inside the constructor of class1 like this:
function obj=class1(c2)
if ~isempty(c2)
obj.cl2=c2;
% obj.cl2.a=obj.a; these are unnecessary now
% obj.cl2.b=obj.b;
% obj.cl2.c=obj.c;
end
end
but you must add as well to the constructor of class2 the following:
function obj=class2()
obj = obj@class1([]);
end
and usually they are called this way in the main script:
bb = class2; aa = class1(bb);
As you notice we need to define bb before aa, this is why I preferred the refertochild method, since in my case aa is first defined somewhere in the beginning of the huge program, and in my specific class2 class the turn of bb declaration comes late.

카테고리

Help CenterFile Exchange에서 Construct and Work with Object Arrays에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by