From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
Intaris

Allow for ABSTRACT classes/functions in LVOOP

I would like to make a small workind change on another suggestion found HERE.

 

I would like to be able to declare LVOOP classes as ABSTRACT.

 

One example is a spectrometer class I have developed which provides much of the needed functionality but which is not designed to actually DO anything (Get name, Set Name, GET calibration coefficients, SET calibration Coefficients and so on).  At the moment I can instantiate an object of this class as with any "VALID" class which then just returns an error at run-time because the functionality is not complete.

 

By preventing users from (either willfully or accidentally) dropping what is essentially an abstract class onto the BD of a program we could prevent some awkward bugs.

 

Shane.

23 Comments
Daklu
Active Participant


--------------------------------------------------------------------------------


Intaris wrote:


No I'm asking for exactly the opposite of using "classes on block diagrams"...  And when I say "class" I mean an object of the class of course.


--------------------------------------------------------------------------------


When I say "class" I'm referring to the more general OOP meaning of the term--the class definition.  Strictly speaking we do not, and cannot, use classes on block diagrams or front panels.  Each class has exactly one definition--the lvclass file.  You could say the lvclass file is the class.  Once you drop it on your block diagram it is no longer a class, it is an object of the type defined by the class.

 

Virtual classes can't exist in Labview because of these opposing requirements:

1. You cannot instantiate an object from an abstract class.

2. Labview automatically creates objects when a class is dropped on a vi.

 

To work around this I suggested figuring out some way to drop "classes on block diagrams."  It would likely have to be a new data type that, rather than containing 'class data' like objects, contains 'class definition data.'

 

So you see, you really ARE asking for "classes on block diagrams."  🙂

Intaris
Proven Zealot

Virtual classes (I thought only methods could be virtual) are something else.  I'm not referring to virtual classes (or methods).  For the sake of it, isn't a Dynamic Dispatch method essentially a virtual method?

 

Also, a class which is purely abstract (no private data and no non-abstract methods) is (IIRC) an interface.  I'm not referring to interfaces here.  The benefits and drawbacks of interfaces is best discussed elsewhere.

 

My ideal solution would be as follows:

We have a class X.

 

1) Class X is declared as ABSTRACT when it contains one or more methods which are also flagged as ABSTRACT. The class is not manually labelled abstract, it is a function of the class method definitions.

 

2) An ABSTRACT method (VI) is a VI whose connector pane is defined but whose implementation is non-existant (or ignored in this case since we need FP and BD for a connpane definition).  An abstract method must be Dynamic dispatch.

 

3) X may or may not contain its own data and methods which are NOT declared as abstract (both dynamic dispatch AND static methods).  Private data is accessible only via dedicated accessor methods which are NOT abstract (and not dynamic dispatch).

 

4) X CANNOT be instantiated, that means we CANNOT place an object constant of the type X on a BD.  An object of Type X on the FP must be allowed due to the implementation of non-abstract methods for the class.

 

Point 4) leads to the following problem: How to handle static methods for X which should not be inherited but must essentially have an object of the type "X" on the FP (needed for casting child objects at run-time).  This seems to violate the "noninstantiation" problem.  We could be required, for example, to set the input object to "required" thus forcing the user to (at some stage in the code) use a valid class as an input.

 

The other problem is the "default" object type when for example a FOR loop executed zero times.  I agree that there ARE cases where an actual object of type X on a wire is unavoidable but as with other data types (references spring to mind immediately where the user must simply take care that only valid values are returned) we can catch these with run-time errors as soon as a Dynamic Dispatch method is called for X.

 

We're alreads half way to abstract classes with the new LVOOP feature where child classes MUST implement certain methods.  If we could only manage to stop the instantiation we'd have it (right?).

 

And Daklu, once we have abstract classes, Interfaces are suddenly very very close.   An abstract class with no non-abstract methods is essentially an Interface.  Then having private data makes no sense since it cannot be accessed (only abstract methods).

Intaris
Proven Zealot

I noticed in the new Icon editor that there's already a Glyph for an abstract object..... Interesting.

Daklu
Active Participant

[Wrong post]

Message Edited by Daklu on 08-18-2009 04:32 PM
AristosQueue (NI)
NI Employee (retired)

> I noticed in the new Icon editor that there's already a Glyph for an abstract object..... Interesting.

 

Intended for you to use to mark the classes that you never *expect* to instantiate. 🙂 

Don't let it get your hopes up... we had that glyph in the original glyph library for LV classes in LV 8.2.

Daklu
Active Participant

"Virtual classes (I thought only methods could be virtual) are something else.  I'm not referring to virtual classes (or methods)."

 

Brain burp.  The line should have read "Abstract classes can't exist in Labview because of these opposing requirements:"  Such is life when trying to compose a post in disconnected 30 second sessions.

 

We agree abstract classes would be useful.  We agree why implementing them presents a problem in Labview.  We disagree in our preference for implementing them.

 

From what I can tell your implementation of an abstract class is essentially a regular class that has extra restrictions and throws runtime errors if the restrictions are violated.  I don't think that's a good idea because, by definition abstract classes cannot be instantiated and by definition dropping a class on a vi instantiates it.  Both definitions are well established yet one of them must be changed to implement it your way.

 

If there were a new data type created, a class definition, placing it on a VI would instantiate the class definition, not an object of the type defined by the class.  This makes it possible to place abstract classes on a vi without violating either definition.  (Maybe dropping class.ctl instantiates an object and dropping class.lvclass instantiates a class definition?)  The runtime behavior would be very similar to what you have outlined but the design time behavior probably needs to stay within Labview's "everything is data" paradigm.  (Although I think NI needs to push the meaning of 'data flow' to continue to expand Labview's capabilities.)

 

-------------------------

 

"Also, a class which is purely abstract (no private data and no non-abstract methods) is (IIRC) an interface."

 

A lower case 'i' interface is simply those methods defined in an arbitrary set of code that is available to code outside of the set.  It could be an abstract class, it could be a concrete class, it could be a set of VIs in a library, etc.  A capital 'I' Interface is much more than just a pure abstract class.  Although it shares some characteristics of classes, it is a distinct construct and operates under different rules.

 

"And Daklu, once we have abstract classes, Interfaces are suddenly very very close."

 

I wouldn't say very very close, but definitely closer, which is why I voted for the idea with my first post.  🙂

Daklu
Active Participant
I was reading The Decisions Behind the Design (again) and noticed LV already separates the object data from the object type data.  (See 'What is the in-memory layout of a class?')  Would it be difficult to create fp and bd representations of the object type data?
F._Schubert
Active Participant

I'm pretty green in LVOOP, but here my ideas:

* An abstract object might only be returned by a type cast to that base class (so no dropping of a abstract object is possible, there is always an non-abstract object)

* Every abstract class must have an 'default implementation', which is returned as default data in for loops, whatever... and implements all methods declared abstract (generating run-time errors being the recommendation, but could also return default data in case of simple accessor methods).

* I'm not sure wether the dafault implementation should also be non-droppable, but the general philosophy behind is: let the users come up with a solution and then force them to use the best that emerged.

 

Felix

Intaris
Proven Zealot

Felix,

 

you've understood my suggestion perfectly.

 

Aspecially your first point is somehting which (according to my limited knowledge of the behind-the-scenes workings of LV) should be do-able.

 

Shane.

CoastalMaineBird
Trusted Enthusiast

FWIW, I would like to see abstract METHODS, applicable to a concrete CLASS.

 

IOW, I would like to see a method attribute in the parent's ITEM SETTINGS that says descending classes MUST OVERRIDE (a setting we have now) and also a setting that says descendants must NOT call the parent method (opposite of a setting we have now).

 

Together those two would make the parent method abstract - it would do nothing except define the terminals.

 

When creating an override, the child would look exactly like the parent - the diagram would have the IF ERROR case structure, instead of calling the parent.

 

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks