Overriding "get"-able properties.

18 ビュー (過去 30 日間)
Steve Juranich
Steve Juranich 2012 年 3 月 6 日
コメント済み: Andrew Sandeman 2022 年 4 月 30 日
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!

採用された回答

Steve Juranich
Steve Juranich 2012 年 3 月 7 日
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 件のコメント
Minseok Song
Minseok Song 2021 年 5 月 16 日
@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 2022 年 4 月 30 日
@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?

サインインしてコメントする。

その他の回答 (2 件)

Andrew Newell
Andrew Newell 2012 年 3 月 6 日
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 件のコメント
Steve Juranich
Steve Juranich 2012 年 3 月 6 日
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.

サインインしてコメントする。


Daniel Shub
Daniel Shub 2012 年 3 月 7 日
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 件のコメント
Steve Juranich
Steve Juranich 2012 年 3 月 7 日
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.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCreating and Concatenating Matrices についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by