Incorrect "Creating an instance of the Abstract class is not allowed"
11 views (last 30 days)
Show older comments
Hi! Trying to instantiate a derived class, query_dev, whose classdef has not a single occurrence of the word Abstract, I get the complaint "Creating an instance of the Abstract class 'query_dev' is not allowed." I've searched my Matlab path--using, separately, "query_dev" and "Abstract"--for other files that might be defining the class, and come up empty handed. Due to the nature of the problem (I guess), even setting a break point at the very first executable line of the constructor is useless (i.e., the error is returned before the break point is reached). Restarting Matlab also didn't fix.
Below is my code (minus comments), first the (Abstract) parent class, then the "problem child." Thanks for your help.
classdef SQLstatement_dev < handle
properties
conn;
tbls = {};
result = {};
issuedStatementError = false;
issuedAvailableError = false;
devVer;
end
properties (Dependent = true)
DBname;
statement;
availableTables;
availableColumns;
end
methods
function SQLobject = SQLstatement_dev(DBname, un, pwd, devVerOverride)
if nargin < 4
SQLobject.devVer = is_devVer(SQLobject);
else
SQLobject.devVer = devVerOverride;
end
if ~SQLobject.devVer
SQLobject.conn = database(DBname, un, pwd);
if ~isempty(SQLobject.conn.Message)
disp(SQLobject.conn.Message)
else
disp(['Connection to database ' SQLobject.DBname ' opened successfully!'])
end
end
end
function delete(obj)
try
close(obj.conn);
catch me
end
end
function name = get.DBname(obj)
if ~obj.devVer
name = obj.conn.Instance;
else
name = 'Development Version: database connection not established on purpose.';
end
end
function S = get.statement(obj)
try
S = obj.assembleStatement;
catch me
if obj.issuedStatementError
S = getReport(me);
obj.issuedStatementError = false;
else
disp('Sorry, attempt to assemble statement failed!')
disp('More info is in this object''s "statement" field.')
obj.issuedStatementError = true;
end
end
end
function aT = get.availableTables(obj)
try
if ~obj.devVer
tmp = fetch(exec(obj.conn, 'select Name from sys.Tables'));
aT = tmp.Data;
else
aT = {};
end
catch me
aT = getReport(me);
if obj.issuedAvailableError
obj.issuedAvailableError = false;
else
disp('Sorry, attempt to get available tables failed!')
disp('More info is in this object''s "availableTables" field.')
obj.issuedAvailableError = true;
end
end
end
function aC = get.availableColumns(obj)
aC = struct.empty;
if ~isempty(obj.tbls)
cat = get(obj.conn, 'Catalog');
sch = schemas(obj.conn, cat);
for t = obj.tbls
for s = sch
if ismember(t, tables(obj.conn, cat, s))
aC.(t) = columns(obj.conn, cat, s, t);
break;
end
end
end
end
end
function addPropVals(obj, prop, newElements)
if ismember(prop, fieldnames(obj))
obj.(prop) = extendArray(obj.(prop), newElements);
end
end
end
methods (Abstract)
S = assembleStatement(obj);
submitStatement(obj);
setPropVals(obj, prop, elements, extend);
getPropVals(obj, prop);
end
end
classdef query_dev < SQLstatement_dev
properties
columns = {};
orderBy = {};
where = '';
end
methods
function qObject = query_dev(DBname, un, pword, parameters)
if nargin < 4
parameters = struct.empty;
end
if nargin < 3
pword = '';
end
if nargin < 2
un = '';
end
if nargin < 1
DBname = '';
end
qObject = qObject@SQLstatement_dev(DBname, un, pword);
paraFields = fieldnames(parameters);
for prop={'columns', 'tables', 'orderBy', 'where'}
prop = prop{:};
if ismember(prop, paraFields)
qObject.(prop) = extendArray(qObject.(prop), parameters.(prop));
end
end
end
function errCode = setPropVals(obj, prop, elements, extend)
if nargin < 4
extend = false;
end
errCode = '';
if ~(isequal(prop, 'where') || iscell(elements))
elements = {elements};
end
switch prop
case 'where'
if ~ischar(elements)
errCode = 'query.setPropVals error: wrong type for where clause';
end
case 'tables'
if numel(elements)~=1
errCode = 'query.setPropVals error: received more than one value for tables';
elseif numel(elements)==1 && ~extend
errCode = ['query.setPropVals error: asked to make tables contain more than '...
'one element; this is not allowed in a "non-join" query'];
elseif ~ischar(elements{1})
errCode = 'query.setPropVals error: wrong type for tables';
end
case 'columns'
for i=1:length(elements)
if ~ischar(elements{i})
errCode = ['query.setPropVals error: at least one value for columns is '...
'the wrong type'];
end
end
otherwise
end
if ismember(prop, fieldnames(obj))
obj.(prop) = elements;
end
end
end
end
0 Comments
Accepted Answer
Pierre
on 16 Aug 2011
query_dev inherits the abstract methods
methods (Abstract)
S = assembleStatement(obj);
submitStatement(obj);
setPropVals(obj, prop, elements, extend);
getPropVals(obj, prop);
end
declared in SQLstatement_dev, but none of those methods but setPropVals is implemented in query_dev. All abstract methods from base classes have to be implemented in the class to be instantiated.
I implemented dummy-methods for the unimplemented methods which solved the "abstract-issue".
0 Comments
More Answers (1)
Daniel Shub
on 16 Aug 2011
There is a lot of code but it looks like SQLstatement_dev defines the abstract methods assembleStatement, submitStatement, setPropVals, and getPropVals. These are passed down behind the scenes to query_dev. The query_dev class defines setPropVals, but not assembleStatement, submitStatement, and getPropVals. You need to define those abstract methods in query_dev.
5 Comments
Daniel Shub
on 17 Aug 2011
The chances that the Mathworks sees this are greatly increased if you submit it to them as a product enhancement. I don't see a reason the error message could not be improved. I doubt mlint could detect this. Mlint does not know about the superclass properties and methods, if the superclass is not on the path while you are editing the subclass.
See Also
Categories
Find more on Logical in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!