Why can't a concrete subclass use size and validator functions on abstract superclass properties?

조회 수: 8 (최근 30일)
Hello all,
I will throw together a little example here; lets create an abstract super class (containing mixed abstract and concrete properties),
classdef (Abstract) abstractSuper
properties
conc (:,1) = zeros(10,1)
end
properties (Abstract)
abst
end
end
where conc is a concrete property initially set for all sub-classes, and I have some abstract property that may have abstract methods associated with it.
Now I create a concrete sub-class.
classdef concreteSub < abstractSuper
properties
abst (1,3) char = 'tst';
end
end
where I want to enforce the property abst as being a 1x3 char vector. Unfortunately, trying to instantiate a concreteSubObj returns
"Error using concreteSub
Size and validator functions not supported for properties defined as abstract in superclasses. Property 'abst' is defined as abstract property in
superclass 'abstractSuper'."
Question
I understand that I cannot use the size/validator in my concrete class, since I defined it as abstract in my super. I do not understand why, since I thought that the point of abstraction was to define an interface, while leaving complete freedom to the concrete subclasses. I also cannot partially define abst in abstractSuper and override it in concreteSub, (e.g. define it in the super, and then add the size/validator function to the sub-class).
I had hoped to do something like force the property to be a character vector in the super, and then be 3 chars long in the sub, but that is even further beyond where I am stuck in this example.
TLDR: Why does defining an abstract property in a superclass prevent me from using size/validator functions in the concrete sub-class?

답변 (5개)

per isakson
per isakson 2019년 11월 2일
The R2019b doc on Validate Property Values says
[...]
Abstract Property Validation
You can define property validation for abstract properties. The validation applies to all subclasses that implement the property. However, subclasses cannot use any validation on their implementation of the property. When inheriting validation for a property from multiple classes, only a single Abstract property in one superclass can define the validation. None of the superclasses can define the property as nonAbstract.
Try this
>> cs = concreteSub
cs =
concreteSub with properties:
abst: 'tst'
conc: [10×1 double]
where
classdef (Abstract) abstractSuper
properties
conc (:,1) = zeros(10,1)
end
properties (Abstract)
abst (1,3) char
end
end
classdef concreteSub < abstractSuper
properties
abst = 'tst';
end
end
  댓글 수: 3
per isakson
per isakson 2021년 11월 18일
편집: per isakson 2021년 11월 19일
"This DOES NOT answer the question" Answers are not exclusively for the OP.
"asks for a reason why this is designed the way" The MathWorks rarely justifies design decisions in public.
"[...] is clearly a bug" I fail to reproduce the bug you report. I've added the line
color {mustBeMember( color, {'yellow','green','blue'} )}
to abstractSuper and run this script
%%
cs = concreteSub;
%%
cs.color = 'red';
Error setting property 'color' of class 'abstractSuper'. Value must be a member of this set:
'yellow'
'green'
'blue'
%%
cs.abst = '12345'; % this statement isn't executed, since the previous errors
I get the same result here and on R2018b.
per isakson
per isakson 2021년 11월 18일
편집: per isakson 2021년 11월 19일
Ok, R2018b doesn't have mustBeA
Now, I've added the line
prop {mustBeA( prop, 'MyClass' )}
to abstractSuper and run
%%
cs = concreteSub;
%%
cs.prop
ans =
MyClass with properties: A: 1 B: 2
cs.prop = MyClass(3,4);
cs.prop
ans =
MyClass with properties: A: 3 B: 4
%%
cs.prop = table(5,6);
Error setting property 'prop' of class 'abstractSuper'. Value must be one of the following types: 'MyClass'.
Isn't this the expected behavior?

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


Nikolaus Koopmann
Nikolaus Koopmann 2019년 11월 1일
i have the same question

Sören Kohnert
Sören Kohnert 2020년 4월 17일
You can use a set method in comination with assert() in your subclass to define different validators for each subclass.
classdef (Abstract) abstractSuper
properties (Abstract)
abst
end
end
classdef concreteSub < abstractSuper
properties
abst
end
methods
function obj = set.abst(obj,value)
assert(ischar(value) && all(size(value) == [1,3]))
obj.abst = value;
end
end
end
  댓글 수: 2
Nikolaus Koopmann
Nikolaus Koopmann 2020년 4월 17일
or like
classdef concreteSub < abstractSuper
properties
abst
end
methods
function obj = set.abst(obj,value)
validateattributes(value,{'char'},{'size',[1 3]});
obj.abst = value;
end
end
end
Thomas Michiels
Thomas Michiels 2021년 11월 17일
both very good solutions, but OP asks for a design reason, not a workaround

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


Marco Schmid
Marco Schmid 2023년 12월 6일
I want to use class validation in my subclass for a abastract property.
The Workaround is not a solution because I want to use the autocomplete in my subclass for the property.
When will you offer a solution for this?

Jan Kappen
Jan Kappen 2024년 7월 23일
편집: Jan Kappen 2024년 9월 11일
Same question here. Is this something being subject to change or is it fixed?
Background of this question is not about validation functions but overloading or making the type more concrete in the subclass.

카테고리

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