Overriding "get"-able properties.

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!

 Risposta accettata

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 Commenti

Jonathan
Jonathan il 31 Mag 2017
2017 and we still need to do this! I don't understand the nature of these functions either, but overloading getters seems quite a natural thing to do to me.. I'm surprised this hasn't been fixed by now.
2020 and we still need to do this!
Will be good to now if they are planning to support overriding getter setter !
Giving the ability to override property access methods in subclasses could result in instances of subclasses not being valid instances of the superclass. Consider two classes:
classdef triangle
properties
sides
end
methods
function obj = set.sides(obj, n)
assert(n == 3, 'A triangle MUST have three sides!')
obj.sides = n;
end
end
end
I know this class hierarchy makes no sense, but if you could override set.sides:
classdef square < triangle
methods
function obj = set.sides(obj, n)
assert(n == 4, 'A square MUST have four sides!')
obj.sides = n;
end
end
end
You could make a square, give it four sides:
S = square;
S.sides = 4
isa(S, 'triangle') % true
and create a triangle with four sides.
For this reason I'm not saying it's impossible that we would allow it, but I wouldn't hold your breath waiting for it.
@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?
@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?

Accedi per commentare.

Più risposte (2)

Andrew Newell
Andrew Newell il 6 Mar 2012

0 voti

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 Commento

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.

Accedi per commentare.

Daniel Shub
Daniel Shub il 7 Mar 2012

0 voti

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 Commento

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.

Accedi per commentare.

Categorie

Scopri di più su Loops and Conditional Statements in Centro assistenza e File Exchange

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by