필터 지우기
필터 지우기

Validate property is a subclass of an abstract class

조회 수: 38 (최근 30일)
men8th
men8th 2020년 8월 25일
댓글: Tim Johns 2021년 8월 25일
I've just upgraded from 2018b to 2020a and some of my code has stopped working. With release 2018b the following code did not throw an error. The idea is that myProperty must always be a subclass of myAbstractClass.
classdef myClass
properties (Abstract)
myProperty(1,1) myAbstractClass
end
end
When I attempt to use myClass in release 2020a I get the following complaint: "Error defining property 'myProperty' of class 'myClass'. Class myAbstractClass is abstract. Specify a default value for property myProperty."
Having read the documentation carefully (https://uk.mathworks.com/help/matlab/matlab_oop/property-size-and-class-validation.html#bvklfs7-1) I can see that Matlab is attempting to assign a default value to myProperty which is an empty instance of myAbstractClass. At this point the code fails because it is not possible to instantiate an abstract class. Presumably the default value was assigned differently in 2018b or the checks were less rigerous. Anyway, I've now got a codebase which doesn't work and needs fixing.
Obviously I could write my own property validation function to get the behaviour I require, or I could do validation in the setter. I've used the same trick in other places in the code, so ideally I don't want to spend ages writing custom property validation functions or modifying setters. Is there an elegant way to deal with this? Something like a mustBeClass validaiton function?

답변 (1개)

Tim Johns
Tim Johns 2020년 9월 2일
Hi Tim,
I can see that Matlab is attempting to assign a default value to myProperty which is an empty instance of myAbstractClass. At this point the code fails because it is not possible to instantiate an abstract class.
Correct. So what you need to do is specify a default property value that is a concrete class:
classdef MyClass
properties (Abstract)
myProperty(1,1) MyAbstractClass = MyConcreteClass()
end
end
Where for example:
classdef (Abstract) MyAbstractClass
methods (Abstract)
foo(obj)
end
end
classdef MyConcreteClass < MyAbstractClass
methods
function foo(obj)
% Implementation
end
end
end
Tim
  댓글 수: 2
Thomas Michiels
Thomas Michiels 2021년 8월 25일
i have the exact same issue using the MustBeA validator.
the annoying part is that i don't want to set a default value as this will get passed in the constructor. As far as i've noticed, this scenario is not decently supported due to the 0argument constructor requirement. But also the fact that almost none of the validators accept empty defaults is a huge issue for the use of abstract classes as a requirement.
the only decent solution for using abstract classes when you don't want to define a concrete class default is implementing your own `MustBaAOrEmpty(obj, classtr)`
Tim Johns
Tim Johns 2021년 8월 25일
Hi Thomas,
MATLAB needs to be able to initialise property values. If you define constraints on that value such as size, type, or validation functions, the initial value must also meet those constraints - you can't have a "null". A second restriction is that you cannot instantiate abstract classes.
Together, these restrictions mean that if you are imposing an abstract type restriction on a property, you need to provide a concrete instance as an initial value. (I think you know this but wanted to clarify.)
The way I normally handle this is by implementing a "NoOp" subclass for default values that implement the required interface. It can also be useful for testing when you don't actually care about that property. The code would be the same as my original answer, but foo would actually do nothing rather than having some implementation. I don't find doing this to be onerous.
I hope that helps.

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

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by