OO, I'm dipping my toe into OO...

Posted by ChUIMonster on 15-Mar-2009 11:59

I've decided to refactor some of my less than properly structured code.

I have a number of methods which are common to several classes. My initial implementation put them into an include file It seemed to me that the obvious thing to do would be to put them in a MyClass.cls and allow them to be inherited. So I went ahead and did that and, glory be! It actually worked with a fairly minimal amount of effort.

However...

Most of the classes that use these common methods are Forms. So I created my parent class inheriting Form.

But one of the classes that needs these common methods is a UserControl. I can't change it to a Form because its container won't allow that. And I can't change the Forms to UserControls.

I'm thinking that there has to be a relatively easy way to solve this problem but I'm not coming up with any concrete ideas.

Does anyone have a suggestion?

All Replies

Posted by Admin on 15-Mar-2009 12:28

Hey Tom, what you are asking for is multiple inheritance. The ABL (and the MS OO languages) don't allow that.

To answer the question, we'd need to know a little more about the nature of those methods: Are those methods really required to be a member of the class? Have these methods access to private members (variables, properties, methods) of the class? Are those methods mostly executed from within the class or outside the class?

Mike

Posted by ChUIMonster on 15-Mar-2009 12:44

They are primarily private to the class and they mostly work with private members.

I was poking around looking at interfaces and thinking there might be some hope in that direction. But I'm not sure that that makes sense.

Posted by Admin on 15-Mar-2009 12:57

Interfaces would help to create a common type that could be used to access the methods of your inherited Form and the inherited UserControl (from outside the classes). Interfaces members are by definition public. So won't help you much here.

Posted by ChUIMonster on 16-Mar-2009 06:56

Yeah, it didn't take long to see that that wasn't going to solve my problem

For the moment I think I'll just go back to the include file. I've got bigger fish to fry right now.

Posted by Håvard Danielsen on 16-Mar-2009 14:46

I assume the common methods are used by the controls in the Form and not by the Form itself.

If this is the case you should (consider) add(ing) them to another User Control that also inherits your common behavior and then add this User Control to the form.

Posted by ChUIMonster on 16-Mar-2009 14:55

You are correct.

Specifically these methods all have to do with supporting behaviors that I want to see in UltraNumeric and UltraText editors. I have come to the realization that the "proper" thing to do would be for me to create my own derived versions of these controls.

I'll probably do that in the next refactoring pass that touches on this stuff.

Posted by fixitchris on 30-Sep-2009 12:57

Don't both a Form and UserControl inherit from the same superclass?  How does this work in ABL?  What about late binding?

  In .NET both Form and UserControl inherit from Component all the way down to System.Object...

Posted by Admin on 30-Sep-2009 13:03

That's no different in the ABL. The ABL does not change the class hierachie of the .NET Framework at all!

System.Object inherits from Progress.Lang.Object - that's the only difference / addition.

Posted by Thomas Mercer-Hursh on 30-Sep-2009 13:17

Right, but if I am reading this right, the .NET inheritance tree doesn't help Tom since he wants to add ABL methods.  No?

For some reason, I don't recall this thread from when it first came by, but it seems that the first thing we need to know, as you said earlier, is a bit more about the methods.  There is something a little questionable off the top about a Form and UserControl wanting to have the same methods since they are different sorts of beast, although one might want similar signatures.  If the signatures were in fact identical, but the implementations potentially different, then I might go with an interface to define the signature and two separate inheritance trees, one for forms and one for user controls.

But, again, one would like to know more about the methods.

Posted by fixitchris on 30-Sep-2009 13:24

Is this Progress.Lang namespace available on my file system?  I can't find it in the GAC.

Posted by Peter Judge on 30-Sep-2009 13:32

fixitchris wrote:

Is this Progress.Lang namespace available on my file system?  I can't find it in the GAC.

The Progress.Lang classes are only available from within the AVM (ie ABL).

-- peter

Posted by Peter Judge on 30-Sep-2009 13:33

For some reason, I don't recall this thread from when it first came by, but

it seems that the first thing we need to know, as you said earlier, is a bit

more about the methods.

>There is something a little questionable off the top

about a Form and UserControl wanting to have the same methods since they are

different sorts of beast, although one might want similar signatures.

They do both inherit from System.ComponentModel.Component, so there's clearly some commonality.

AFAIK, it's also not possible to "insert" inheritance up the class hierarchy*, so you can't simply insert your own class between Microsoft's System.ComponentModel.Component and System.Windows.Forms.Control so that all the Forms, UserControls and other controls all inherit the same behaviour.

Interfaces are the way to go for defining those methods; if you want the executable code in one class, then some sort of Delegate pattern is probably needed too.

-- peter

_* Unless you have the source code or do the special magic the AVM does.

Posted by Admin on 30-Sep-2009 13:34

The Progress.Lang.* classes are no .NET types. The ABL has it's own type modell. Progress.Lang.* must be implemented in the Progress runtime.

Progress.Windows.* contains .NET classes. It's types are contained in %DLC%\bin\Progress.NetUI.dll

Posted by Admin on 30-Sep-2009 13:37

_* Unless you have the source code or do the special magic the AVM does.

I'm pretty sure we could use IJW from C++, but not from within ABL code, right?

Posted by fixitchris on 30-Sep-2009 13:47

Ok, makes sense.

What is the purpose of Progress.NetUI?

Posted by Thomas Mercer-Hursh on 30-Sep-2009 13:50

They do both inherit from System.ComponentModel.Component, so there's clearly some commonality.

Yes, but that is a bit like saying that two ABL classes have commonality because they inherit from Progress.Lang.Object ... not quite that bad, of course, but also not a strong statement.

The key here though, I think, is that there is an existing .NET class hierarchy with a fork in it and Forms on one branch and UserControl on another branch (I don't know the actual tree, but this seems implied by prior statements).  If so, then one can't really put this code into a common base without diddling with the .NET hierarchy .. correct.  Therefore, it seems that, if one is doing this in ABL, one has to deal with it *after* the split, which implies two separate implementations.

As you say, if the two are truly identical methods, one might refer to a delegate, depending on what Tom actually wants to do, but if he is acting on private members, that may not be a solution.

Posted by Admin on 30-Sep-2009 13:50

That's part of the bridge, the magic glue between Progress and .NET.

It contains stuff like the Progress.Data.BindingSource (aka ProBindingSource) or the Progress.Windows.Form, a base .NET form that provides interoperability features between ABL windows and .NET Forms etc..

The GUI for .NET developers guide is full of stuff that Progress added in 10.2A to implement the bridge!

Posted by Thomas Mercer-Hursh on 30-Sep-2009 13:51

Do you mean what is not called ABL GUI for .NET?

Its purpose to be able to use [most] ,NET controls to create an arbitrarily nice UI, but to do all of the actual programming in ABL.

At this point, its purpose is strictly UI.

Posted by fixitchris on 30-Sep-2009 14:07

I don't know enough about ABL <> .NET but a common interface should work something like this:

class myCommonABLMethods()

   method1(Component)

   method2(Component)

interface ICommonComponent

   Component View { get; }

class myForm: Form, ICommonComponent

  Component View { get { return this; }}

class myUserControl: UserControl, ICommonComponent

  Component View { get { return this; }}

maybe generics could help... http://msdn.microsoft.com/en-us/library/xwth0h0d(VS.80).aspx

Posted by fixitchris on 30-Sep-2009 14:10

Thanks guys.  So the binding source is the actual glue that keeps the db context tied to the UI?

Posted by fixitchris on 30-Sep-2009 14:15


AFAIK, it's also not possible to "insert" inheritance up the class hierarchy*, so you can't simply insert your own class between Microsoft's System.ComponentModel.Component and System.Windows.Forms.Control so that all the Forms, UserControls and other controls all inherit the same behaviour.


Right, you would be forced to implement your own, overriding methods where you can.

Posted by Thomas Mercer-Hursh on 30-Sep-2009 14:26

Support for .NET classes with generics is coming in 10.2B shortly.

We will still have to wait for ABL classes with generics, unfortunately.

Posted by Thomas Mercer-Hursh on 30-Sep-2009 14:27

Hopefully, the binding source is tied to local data, not the database.  One would never want the UI talking directly to the database.

Posted by Admin on 01-Oct-2009 06:27

Hopefully, the binding source is tied to local data, not the database.  One would never want the UI talking directly to the database.

With the ProBindingSource adding a local (temp-table/prodataset) layer is pretty important. Binding to the DB works fine for reading and updating existing data. Creating new rows directly in the DB is usually painful as the ProBindingSource requires to create the record pretty early. Usually that will cause the row being released (or querying the ROWID) to the DB with default values. May cause big trouble when two users do that in parallel.

Posted by Thomas Mercer-Hursh on 01-Oct-2009 12:03

My point was that modern architectural best practice would not allow direct DB connections from a client.

Posted by Admin on 01-Oct-2009 12:35

I know and I'm with you on than, Ethan. My point is that is much

easier to convince long time coders when the good architecture also

solves an obvious and already faced real world issue.

This thread is closed