New() Method with Abstract Method() in Base Class

BlitzMax Forums/BlitzMax Programming/New() Method with Abstract Method() in Base Class

Gabriel(Posted 2006) [#1]
I'm looking at something a bit like this :

Type Base
   Method New()
      Open()
   End Method
   
   Method Open() Abstract

End Type

Type Anything Extends Base
   Method Open()
      DOSTUFF()
   End Method
End Type


Now for me, the whole purpose of PolyMorphism is that it should always execute what you might call the lowest existing method down the chain of inheritance. In other words, it should be looking at the type you actually created an instance of, and heading back up the "family tree" until it finds a method.

Now I understand why this doesn't work ( although I'm not sure if it would or would not in other languages ) and that's because it's being called by the New() method of the base type, and the new method of the base type can ( apparently ) only see the object as being of the base class, but I want all my objects to open when they are created. Now I *CAN* put an Open() call in every new type, but there are a lot of types and it's a thin end of a wedge. If I have a few of these situations, I'm really doing a lot of stuff in the derived types which I could be doing in base types.

Should this behave as it does and is there a way to achieve what I'm trying to achieve?


dmaz(Posted 2006) [#2]
SuperStrict

Type Base
	Method Create:Base()
		Open()
		Return Self
	End Method
   
	Method Open() Abstract

End Type

Type Anything Extends Base
   Method Open()
      Print "do stuff"
   End Method
End Type


Local t:Anything = Anything(New Anything.Create())
t.Open()

I'm NOT saying this is the best way to do what you want, but at least it's an option. ("do stuff" will be printed twice in the above example)


Koriolis(Posted 2006) [#3]
Should this behave as it does
It's almost a philosphical question here. The thing is, inside Base.New the object still is *only* an instance of new, even if called from Anything.New.
On a more pragmatic side of things, if you can call derived methods when the derived part of the object is not constructed, really bad things can happen (most methods are coded with in mind the insurance that the object is fully constructed - which is kind of sound).

Now, there are clearly cases where you do know that calling a method of the derived type from within the base type cosntructor *is* safe, and usefull.

For the record, the problem is exactly the same in C++, and to attest that your problem is a real one, some famous and estimated C++ coders try to find workarounds to this.

and is there a way to achieve what I'm trying to achieve?
Not that I know, except of course by creating a function "Create" that does the actual job of constructing the object (which is anyway the common way of handling parameters when constructing an object), and call "Open" from that function.


SculptureOfSoul(Posted 2006) [#4]
I'm sure it's possible but it would require that the compiler check to see just what kind of object is being made whenever the base class constructor was called, and then call the virtual method in cases where the actual type of the object being created is the derived type. Of course, it would have to delay the call until after the derived type was created - seeing as the derived type constructor could very well rely on information from the base type. At that point, it's no different from simply calling the method from the derived class's constructor, except for the overhead.

I'm assuming it wasn't included in the compiler design due to the speed sacrifice it calls for.


Winni(Posted 2006) [#5]
I understand Gabriel's point of view and can follow his train of thought. Nevertheless, I would like to add some comments to the philosophical side of things:

Would it be legit that a base class makes assumptions about classes derived from it?

Especially when the base class is an abstract class, as the one in the sample above implicitly is, since it contains an abstract method?

I think BlitzMax's behaviour is justified and correct. Derived classes implicitly do call the constructor of the base class, however, if this base constructor is supposed to call an abstract method, which instance of it would you expect it to call?

This question becomes more critical when the inheritance grows larger and the called method is overloaded several times. And I guess this is one of the reasons why the above code is illegal in all OO-languages.

Multiple inheritance would even add to that chaos (which is the main reason why C-Sharp and Java for example do not support multiple inheritance, except for the use in interfaces/abstract classes). Calling super in multiple inheritance adds to this chaos: To which base class refers super?

In the "good old days" of functional programming we did not have that kind of problem. And amazingly enough, the software still was able to actually solve some problems.

In the past I have worked for a compiler vendor myself, and the C++-developers there only used OO for simple encapsulation, but never for (multiple) inheritance or other more complex constructs. They probably had some good reasons for this. ;-)


H&K(Posted 2006) [#6]
Deleted by H&K