Incorrect "Creating an instance of the Abstract class is not allowed"
8 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Pierre
2011-8-16
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 个评论
更多回答(1 个)
Daniel Shub
2011-8-16
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 个评论
Daniel Shub
2011-8-17
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.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Software Development Tools 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!