Validate property is a subclass of an abstract class

14 ビュー (過去 30 日間)
Tim Hattrell
Tim Hattrell 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 件のコメント
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.

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

カテゴリ

Find more on Construct and Work with Object Arrays in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by