Question OOABL, How do I inherit multiple classes?

Cecil

19+ years progress programming and still learning.
I have a selection of independent class objects which all different functionality and I want to create a new class object which inherits one or more of them. How do I do this, I keep ending up at 'interfaces' but I don't think that's what I want.

Here is what I'm trying to do:

Code:
/** ClassObj1.cls**/
CLASS ClassObj1:
METHOD private void foobarA:
END METHOD.

METHOD private void foobarB:
END METHOD.
END CLASS.

/** LibClassObj2.cls**/
CLASS LibClassObjY:
METHOD private void foobarX:
END METHOD.

METHOD private void foobarY:
END METHOD.
END CLASS.

/** ClassObjABC.cls**/
CLASS ClassObjABC inherit LibClassObj1 LibClassObj2: /** How do I inherit more than one class object??**/

THIS-OBJECT:foobarB().

THIS-OBJECT:foobarX().

END CLASS.
 
Interfaces is correct. Progress oo4gl chooses to not support multiple inheritance.
I seams to me that other programming languages like JAVA, Python & C# and possibly many more don't support multiple inheritance either. It sound like it part of the OOP code of ethics; "I MUST NOT HAVE MORE THAN ONE INHERITANCE CLASS!".

Ok, back to the drawing and try and figure it out.
 
I just finished a C++ course, which is the only language that I know of (I'm sure there are others that I don't know of) that supports multiple inheritance. After learning about the issues involved, for sure it seems like not supporting it is the right choice, language-design wise!
 
Multiple inheritance is not only a good way to blow out your brains, but is quite dubious from an OO theory perspective. ABL *does* allow multiple interfaces per class and even multiple inheritance in sufficiently modern versions. So, you can try telling us what you think you need to do, if you can't sort it yourself.
 
Multiple inheritance is not only a good way to blow out your brains, but is quite dubious from an OO theory perspective. ABL *does* allow multiple interfaces per class and even multiple inheritance in sufficiently modern versions. So, you can try telling us what you think you need to do, if you can't sort it yourself.

Ok, hypothetically lets say I have a common/generic class object file ('common-utils.cls') which I would use for many other projects. The 'common-utils' class object has a handful of methods and one of those methods is used for searching for the existence of a filename. The method (lets call it "file-unique()" will return a character of an filename with a number incorporated into the filename to make it unique. i.e 'report(1).txt'.

In a new class object I want to utilise the 'file-unique()' method but I don't necessarily want instantiate the common-utils class, i.e. NEW. I just want to call 'file-unique()' without creating an object first. My first obvious answer is to inherit the common-utils class object, but the new class object is already using the inherit option with another class object. So how would I utilise the common-utils class object via interfaces?

Does that make sense.
 
No, it doesn't make sense. The methods of your utility class are not a part of the problem space of your new class and thus have no business being a part of the class hierarchy. What is your problem with newing the class to use its methods? Worst case, make it a static method and you don't even have to new the class, but you do have to have pay the price of it staying in memory until the session ends. If it is a class whose methods you use frequently and in many places, that may be acceptable.
 
Worst case, make it a static method and you don't even have to new the class, but you do have to have pay the price of it staying in memory until the session ends.

That's what I need to be doing, "STATIC". I am using WebSpeed exclusively for my Application, so having the class object staying in memory should not be a problem.
 
Be cautious about statics. There are a number of cautions besides staying in memory. E.g., you absolutely don't want to have any DB I/O in there. Note too some interesting issues if the class is not 100% static. PSC changed from instance private to class private and that has some potentially interesting side effects. None of this happens if you just new the object. There are a variety of other techniques for keeping it a singleton and for providing a registry of classes like this so that you don't have to find it. But, if you make it a singleton, you can new it everywhere you need it and not worry about having more than one copy. Statics are handy, but with a price.
 
@tamhas, ' ABL *does* allow multiple interfaces per class and even multiple inheritance in sufficiently modern versions', may I ask which versions or if there is some special syntax? This is the syntax definition from the most recent documentation that I can find on progress.com.

CLASS class-type-name [ INHERITS super-type-name ] [ IMPLEMENTS interface-type-name [ , interface-type-name ] ... ] [ USE-WIDGET-POOL ] [ ABSTRACT | FINAL ] :
 
I am not sure what you mean by "special syntax". As I recall, ABL has supported single inheritance and multiple interfaces since the beginning. The addition has been interface inheritance. The techniques for singleton are not a part of the CLASS statement. I posted one on OE Hive a zillion years ago and there is a discussion on the topic in the documentation.
 
A few posts back, you stated that Progress supports multiple inheritance (not just multiple interfaces), whereas the most recent documentation seems to indicate this is not so. So I was wondering if you knew of some trick to make MI work. I was interested because so few languages support MI and it seems out of character that Progress would. That's all.
 
Typo. What I was trying to say was that it supported implementation inheritance in sufficiently modern versions. Multiple inheritance is not supported because PSC, right in my opinion, feels that it is a bad thing.
 
I don't mean to badger you ... but since you obviously know your way around ABL OO and I don't at all, care to answer:

1) What's your aversion to DB IO inside statics? I have no experience of this and am genuinely curious. In JavaLand, I don't see why it is necessary bad, so maybe it's an ABL-specific transaction-scope type thing?

2) What's your opinion of the current state of GC for ABL objects? Last I checked, many moons ago, it was barely a gleam in PSC's eye and the company line was still "you CREATE/NEW it, you DELETE it". I ask because of what you said about statics and staying in memory. I guess there is nothing to DELETE, but how is a static object different from doing an old-style non-persistent RUN?
 
I don't remember the details, but there was a PEG discussion on some nasty side-effect which occurred because someone was doing DB IO in a static. I didn't pay it a lot of mind since it was the kind of thing I just wouldn't do.

On GC, it works fine with one qualification. I still believe in managing lifecycle explicitly whenever possible and have shot myself in the foot by forgetting to do so. That is not simple create/delete since sometimes it is the consumer of an object that knows when the lifecycle is over, e.g., a message object.

The one big exception is circular references and this is one of the places where I have shot myself in the foot. I have a tool which involves several SAX readers. This still has to be a PP, but thanks to a suggestion (yeah David Abdala) I wrote the PP so that it was passed a reference to the primary object and it had stubs for each of the relevant callbacks. Each stub then called back to a method on the primary object to do the actual processing. This puts all the real logic in the main object and preadapts for when we can use methods as callbacks.

But, it also means that the PP has a reference to the primary object and the PP was cleaned up in the destructor of the primary object. The destructor never got called when I fell back to the driver object which was managing the process. So, I moved the cleanup of the PP out of the destructor and also put an explicit delete in the driver.

The other more subtle exception is subscribing to class events. The subscriber has a reference back to the publisher so when one quits using the publisher it doesn't get cleaned up unless one specifically goes through and gets rid of the subscriber as well.

This has been discussed in the OO Info Exchange at the PUG Challenge Americas last year and the PUG Challenge EMEA in November (http://www.oehive.org/OOWishList) and they recognize that it might be possible to recognize that there are two or more objects like this with references to each other, but nothing else with a reference into the pair (duprass anyone?) and then clean them up, but it isn't on the roadmap.

Statics are really a whole different animal, though. Any code in a static is locked into memory for the life of the session and will only be released at the end of the session. Period. This means, for example, in PDSOE, that unless you use a separate AVM for testing (which I do anyway), the static ... the version as it was at the time of the first run ... is locked into the memory no matter how many test runs you do. That could surprise you!
 
The DB access in statics issue is just like with a PP - if you leave some reference in scope or lock a record and forget about it...
 
Back
Top