#1488 Static slots name conflicts

go4 Sun 10 Apr 2011

I want to let the Coord2D and Coord3D work with Serialization:

@Serializable { simple = true }
const class Coord2D
{
  Float x
  Float y

  const static Coord2D defVal := Coord2D(0f, 0f)

  static Coord2D? fromStr(Str s, Bool checked := true)
  {
  }
}
@Serializable { simple = true }
const class Coord3D : Coord2D
{
  Float z

  const static Coord3D defVal := Coord3D(0f, 0f, 0f)

  static Coord3D? fromStr(Str s, Bool checked := true)
  {
  }
}

The compiler say:

Cannot override non-virtual slot 'Coord2D.defVal'
Cannot override non-virtual slot 'Coord2D.fromStr'

With curiosity, it is valid in java. Why the fantom not allowed?

Thanks.

DanielFath Sun 10 Apr 2011

In java all methods and fields are virtual, no? In Fantom opposite is true. Just add virtual modifier and you'll be fine. I think you can search previous discussions for more info why all methods are non-virtual.

brian Sun 10 Apr 2011

Right now we don't allow overrides of anything from a base class except virtual methods. This includes static methods which are a bit tricky since they do inherit into your subclass namespace, but could potentially be "overridden" in a subclass by another static method. But its a bit messy with the clean slot lookup by simple name, so I've been keeping the restriction for now.

go4 Mon 11 Apr 2011

Thanks DanielFath and brian

The static slots belonging to the class. Every class has its own static methods and static fields. I don't think this is a override.

go4 Tue 12 Apr 2011

The static overriding is at hand:

class Base
{
  static virtual foo() {...}
}
class Sub : Base
{
  static override foo() {...}
}

We don't need any special treatment.

brian Thu 14 Apr 2011

What I did with constructors is that they don't inherit into a subclass namespace. Consider this program:

class Bar
{
  new makeBar() {}
  new make() {}
  static Void s() {}
}

class Foo : Bar
{
  new make() : super.make() {}
  Void main()
  {
    typeof.slots.each |s| { if (s.parent != Obj#) echo(s.qname) }
  }
}

It will print:

play_0::Bar.s
play_0::Foo.make
play_0::Foo.main

If you try to call makeBar unqualified from within Foo it will be a compiler error.

Static methods are sort of a cross in that you they do inherit into the subclasses namespace, but are always scoped by the parent class. However with the -> operator you can use statics like virtual methods already. Consider this case:

class FactoryA { static Str makeOne() { "FactoryA" } }

class FactoryB { static Str makeOne() { "FactoryB" } }

class Test
{
  Void main()
  {
    echo(FactoryA()->makeOne)
    echo(FactoryB()->makeOne)
  }
}

Sort of cool and I actually use that technique on occasion for more reflective/meta-level programming.

go4 Sun 17 Apr 2011

Thank you for the explanation.

I look forward to:

class A
{
  static Str foo() { "call a" }
}

class B : A
{
  static override Str foo() { "call b" }
}

class C : B
{
}


A.foo  //call a
B.foo  //call b
C.foo  //call b

A().foo  //compiler error
B().foo  //compiler error
C().foo  //compiler error

A()->foo  //call a
B()->foo  //call b
C()->foo  //call b

A().typeof->foo  //call a
B().typeof->foo  //call b
C().typeof->foo  //call b

Login or Signup to reply.