Overriding "get"-able properties.

18 vues (au cours des 30 derniers jours)
Steve Juranich
Steve Juranich le 6 Mar 2012
Commenté : Andrew Sandeman le 30 Avr 2022
Let's say I have a class "A" that looks like this:
classdef A
properties (GetAccess = public, SetAccess = protected)
foo;
end
methods
function f = get.foo(self) %#ok<MANU>
f = randn(1, 1);
end
end
end
And now let's say I want to override the "foo" property in a child class that returns a uniformly random variable. In just about every other object-oriented programming language with which I am familiar, I would do the following:
classdef B < A
properties (GetAccess = public, SetAccess = protected)
foo;
end
methods
function f = get.foo(self) %#ok<MANU>
f = rand(1, 1);
end
end
end
But in MATLAB, this is not the right answer. I try this and here's the error that I see:
>> b = B
Error using B
Cannot define property 'foo' in class 'B' because the property has already been defined in the super-class 'A'.
I have tried adding the Dependent tag to the property to no avail, also, Abstract in this case will also not work because (according to the documentation), the properties in the "concrete" classes must be static (i.e., not dynamically calculated).
This is really hindering my work to create a clean design in how some of my tools work together. Can somebody please provide some insight into how to accomplish this?
Thanks!

Réponse acceptée

Steve Juranich
Steve Juranich le 7 Mar 2012
So, I thought a little about the suggestion from Daniel, and I came up with the following:
First, redefine the A class as:
classdef A
properties (GetAccess = public, SetAccess = protected)
foo;
end
methods
function f = get.foo(self)
f = self.get_foo_value;
end
end
methods (Access = protected)
function v = get_foo_value(self) %#ok<MANU>
v = randn(1, 1);
end
end
end
Then, rewrite the B class as:
classdef B < A
methods (Access = protected)
function v = get_foo_value(self) %#ok<MANU>
v = rand(1, 1);
end
end
end
Then instances of both A and B behave as expected, with each access of the foo member yielding a new value from the expected distribution.
Still, this seems REALLY kludgey. I guess it really comes down to the nature of the get.* methods (which I obviously don't understand).
  5 commentaires
Minseok Song
Minseok Song le 16 Mai 2021
@Steven Lord I understand why you say that it's impossible, but I think that is acceptable as polymorphism.
Many people use custom setter or getter functions, and it doesn't look good(because there is a OFFICIAL setter/getter function, but it cannot used.).
I wonder that how can we implement polymorphism in MATLAB?
Andrew Sandeman
Andrew Sandeman le 30 Avr 2022
@Steven Lord Following your example above, is it not the user's responsibility to make a class hierarchy that makes sense? The example above violates Liskov substitution principle since Square "is a" Triangle is not true, and I think that is pretty core principle. Is the restriction there because creating good class hierachies can be difficult and many users may fall into a bad hierarchy like the example above?

Connectez-vous pour commenter.

Plus de réponses (2)

Andrew Newell
Andrew Newell le 6 Mar 2012
The problem occurs because you have to redefine the property foo in addition to the method get.foo. In Modifying superclass properties, it says that there are two circumstances under which you can modify a superclass property:
  1. The value of the superclass property Abstract is true.
  2. The values of the superclass property SetAccess and GetAccess attributes are private.
I don't know if either of these circumstances are useful to you, but at least you know when you can do this.
  1 commentaire
Steve Juranich
Steve Juranich le 6 Mar 2012
Yes, I read that too. The problem here is that the "foo" property in the super-class is _NOT_ abstract. Obviously, the example that I posted was trivial to illustrate the case. But it is not difficult to imagine the super-class having much more functionality to it which relies on an internally randomly generated Gaussian value, while its sub-class wants to retain all of the functionality of the super-class, but rely internally on a uniform random variable. The inheritance mechanism as explained in the documentation doesn't seem to allow for this, while this is sort of a textbook example of how one might use inheritance in other object oriented languages.
Now, it may be true that I might be able to work around this by introducing an abstract class at the top of all of this hierarchy. I will try that as soon as I get the opportunity.

Connectez-vous pour commenter.


Daniel Shub
Daniel Shub le 7 Mar 2012
I think you can either
  1. change the property foo to be a method, which can then be overloaded, or
  2. you can overload subsref.
  1 commentaire
Steve Juranich
Steve Juranich le 7 Mar 2012
Well, true, either of those options would work. But it's also a lot of work for something that really should be straightforward. Your second option, in particular, seems to be an invitation for "unexpected consequences" code.
That's the way I see it, anyway. I'm pretty lazy.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Creating and Concatenating Matrices dans Help Center et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by