How to avoid duplicating code in the constructor and a reset method of a class with class inheritance.

5 visualizaciones (últimos 30 días)
FYI, I asked a similar question about this problem before but did not get a satisfactory answer so I'll ask it in a different way this time to see if that helps.
I have a class hierarchy with inheritance. Each class has a reset method which resets properties to default values set at initialization. I want this reset method to be called at the end of instantiation of each object so that I don't have to have two copies of this code (one in the reset method and one in the object constructor).
In other words, I want to replicate the behaviour of the following code but without duplicating lines 9 and 15. (In my actual application, there is a lot more code to reset the object).
classdef MySuperClass < handle
properties
a0
a
end
methods
function obj = MySuperClass(a0)
obj.a0 = a0;
obj.a = a0; % reset code
end
function increment(obj, i)
obj.a = obj.a + i;
end
function reset(obj)
obj.a = obj.a0; % reset code (duplicate)
end
function disp(obj)
disp(obj.a);
end
end
end
Sub-class with inheritance:
classdef MyClass < MySuperClass
properties
b0
b
end
methods
function obj = MyClass(a0, b0)
obj = obj@MySuperClass(a0);
obj.b0 = b0;
obj.b = b0; % reset code
end
function increment(obj, i)
increment@MySuperClass(obj, i);
obj.b = obj.b + i;
end
function reset(obj)
reset@MySuperClass(obj);
obj.b = obj.b0; % reset code (duplicate)
end
function disp(obj)
disp@MySuperClass(obj)
disp(obj.a);
end
end
end
Note: I have tried replacing the line in the constructors with
obj.reset();
but this results in the reset methods being called twice when instantiating a MyClass object. Although this might not cause any harm, there must be a way to avoid this.

Respuestas (2)

Bill Tubbs
Bill Tubbs el 7 de Sept. de 2022
Editada: Bill Tubbs el 7 de Sept. de 2022
I found one solution. If you put the reset code in a static method, you can call it from within the constructor. Not sure if this is the best but it works.
classdef MySuperClass < handle
properties
a0
a
end
methods(Static)
function reset_static(obj)
obj.a = obj.a0;
end
end
methods
function obj = MySuperClass(a0)
obj.a0 = a0;
MySuperClass.reset_static(obj); % call static method
end
function increment(obj, i)
obj.a = obj.a + i;
end
function reset(obj)
MySuperClass.reset_static(obj); % call static method
end
function disp(obj)
disp(obj.a);
end
end
end
classdef MyClass < MySuperClass
properties
b0
b
end
methods(Static)
function reset_static(obj)
obj.b = obj.b0;
end
end
methods
function obj = MyClass(a0, b0)
obj = obj@MySuperClass(a0);
obj.b0 = b0;
MyClass.reset_static(obj); % call static method
end
function increment(obj, i)
increment@MySuperClass(obj, i);
obj.b = obj.b + i;
end
function reset(obj)
reset@MySuperClass(obj);
MyClass.reset_static(obj); % call static method
end
function disp(obj)
disp@MySuperClass(obj)
disp(obj.b);
end
end
end

Jeff Miller
Jeff Miller el 8 de Sept. de 2022
This is presumably an issue only because you sometimes create objects of the type MySuperClass--not just descendant MyClass objects. (If you never need MySuperClass objects, then it's constructor doesn't need to call it's reset--the descendant's constructor can call its own reset, which in turn calls the MySuperClass reset.)
Another alternative would be to include an optional extra parameter on the MySuperClass constructor which--when present--tells the MySuperClass constructor to skip its reset call. This optional extra parameter would then be included only when the descendant MyClass constructors call the MySuperClass constructor. So, if you made a MySuperClass object normally, it would reset itself on creation, but if you made it from within a descendant, that reset would be deferred until the descendant's reset.
  1 comentario
Bill Tubbs
Bill Tubbs el 8 de Sept. de 2022
Thanks, yes that's right. I want both classes to be usable objects (in fact there are multiple levels). I considered having an Abstract class at the top of the hierarchy but I'm not sure how this would solve the problem. Technically I could put everything except the reset method in the abstract class and then have the sub-class inherit from the abstract class but that seems like overkill.
Your solution of using an argument to flag the reset operation would work.

Iniciar sesión para comentar.

Categorías

Más información sobre Methods en Help Center y File Exchange.

Productos


Versión

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by