Incorrect "Creating an instance of the Abstract class is not allowed"
Mostrar comentarios más antiguos
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
Respuesta aceptada
Más respuestas (1)
Daniel Shub
el 16 de Ag. de 2011
0 votos
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 comentarios
Pierre
el 16 de Ag. de 2011
You didn't even read my answer, did you?! BTW, the "passing down behind the scenes" is desired and obvious behaviour in object oriented programming... I recommend you familiarize more with concepts and techniques of object oriented programming techniques in order to do yourself a favour.
Daniel Shub
el 16 de Ag. de 2011
Come on Pierre, play nice now.
You are correct, I did not read you answer. It was not there when I started writing my answer, and it was only a minute old when I finished my answer. This happens all the time on Answers.
Of course the passing down behind the scenes is a desired and obvious behavior, and I might go so far as to say a required behavior of any OOP that supports inheritance. It seemed to me that David was missing this point since he search his MATLAB path looking for "Abstract." I still think "behind the scenes" is a reasonable description of this behavior.
Pierre
el 16 de Ag. de 2011
Apologies if I offended you, Daniel, I didn't mean doing so: I now realize I actually misread "Daniel" vs "David". For me it looked like the author of the question answered his own question without really understanding the issue although he had gotten a fully qualified answer to his question.
I'm sorry guys, I did wrong, to both of you.
(I was just quite irritable after having read a bunch of the other questions of people asking for getting their work done by contributors...)
David Goldsmith
el 16 de Ag. de 2011
Daniel Shub
el 17 de Ag. de 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.
Categorías
Más información sobre Scope Variables and Generate Names en Centro de ayuda y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!