This class type

That may have been discussed before, but I did not find the right search terms for it. In strongly typed object-oriented languages like C++ or Java, how do you designate the type of the class in class methods?
A typical use would be the return type of factory methods but it would be useful elsewhere too. Eg.

MyClass MyClass::newInstance();

The problem with the code above is that in a derived class, the signature allows newInstance to return an instance of the base class-- the signature is not restrictive enough.

class MySubClass: MyClass
...
MyClass MySubClass::newInstance(); // WRONG newInstance must return MySubClass

There should be some way to tell the compiler that the type returned is that of the class it is invoked on, is there? Or is there simply a covalence rule for return types such that you would write

MySubClass MySubClass::newInstance();

...which looks a bit hackish to me. The signature needs to be written again for each subclass. And it needs to be extended to parameters too for eg. clone

int MyClass::clone(MyClass obj1, MyClass& obj2);

What I am looking for is something like:

ThisClassType MyClass::newInstance();

Any insight is welcome.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

MyType, ThisType, SelfType, ThisClass, etc

The concept comes with various names. Here's a paper on a typed polymorphic lambda calculus encoding: An Object Encoding For SelfType.

Here's a paper on extending Java with it: LOOJ: Weaving LOOM into Java.

Nice, thanks for the links.

Nice, thanks for the links. Seems to be referred to as the binary method problem, where two parameters are of same type. As there does not seem to be an accepted convention for it I will need to come with my own (and look hard on whether I need exact types)

If the binary method problem

If the binary method problem is what you're looking into, Pierce's book "Types and Programming Languages" covers this. For public info, you can start with Pierce and Cardelli's On Binary Methods.

On Binary Methods

That is interesting as well.

In my case, I was looking at class methods rather than instance methods. On the other hand in the paper we have

class PointClass 
  instance variables 
    xValue: real 
    yValue: real 
  methods 
    x: real is return(xValue)
    y: real is return(yValue)
    equal(p: Point): bool is 
       return( (xValue==p.x) && (yValue==p.y) ) 
end class 

class ColorPointClass subclass of PointClass
  instance variables 
    -- xValue and yValue are inherited
    cValue: string
  methods 
    -- x and y are inherited
    c: string is return(cValue)
    -- equal is overriden
    equal(p: ColorPoint): bool is 
        return( (cValue==p.c) && (xValue==p.x) && (yValue==p.y) ) 
end class

If I make equal a class method it will look like

-- class PointClass
  class methods
    equal(p1, p2: Point): bool is 
       return( (p1.xValue==p2.xValue) && (p1.yValue==p2.yValue) )  

-- class ColorPointClass
  class methods
    -- equal is overriden
    equal(cp1, cp2: ColorPoint): bool is 
        return( (cp1.cValue==cp2.cValue) && (cp1.xValue==cp2.xValue) && (cp1.yValue==cp2.yValue) ) 

At this point the methods are invoked with a specific class so there is no binary method issue. But I would like to define them outside the class in a Qualifier (like a mixin):

qualifier Comparable
  class methods
    equal(p1, p2: SelfType): bool
end qualifier

class PointClass is Comparable
...
  class methods
    equal(p1, p2: SelfType): bool is 
       return( (p1.xValue==p2.xValue) && (p1.yValue==p2.yValue) )  
end class

class ColorPointClass subclass of PointClass
...
  class methods
    equal(cp1, cp2: SelfType): bool is 
        return( (cp1.cValue==cp2.cValue) && (cp1.xValue==cp2.xValue) && (cp1.yValue==cp2.yValue) ) 
end class

...
b: bool := Comparable.equal(p1, p2)

Which method should be called when doing Comparable.equal? It will depend on both arguments. So I guess that is a form of multimethod. But with that scheme it is not possible to redefine eg. equal(p: PointClass; cp: ColorPointClass): bool so that makes it more limited than CLOS multimethods.

In certain, very limited

In certain, very, very limited cases you can get the effect (and name it whatever you want) in C++

template<typename MySubClass>
class MyClass {
  virtual MySubClass newInstance() = 0;
};

class ActualSubClass : public MyClass<ActualSubClass> {
  ActualSubClass newInstance() { ... }
};