Re: [Vala] Virtual methods in interfaces



On 28 January 2011 08:51, Abderrahim Kitouni <a kitouni gmail com> wrote:
Hello,

                  في خ، 27-01-2011 عند 16:13 +1030 ، كتب James Moschou:
On 25 January 2011 23:36, Abderrahim Kitouni <a kitouni gmail com> wrote:
but if you remove the override keyword, it works ;-)

So now the question is : is this intentional? I always thought that you
don't need override when implementing an abstract method (and need
override when there is already an implementation), but it seems I was
wrong. This probably needs an answer from Jürg (and the rationale to be
added somewhere in the documentation).

I'm aware that it works if you don't use the override keyword, and it
does seem unintentional, considering that the behaviour of
abstract/virtual/override/new is pretty well defined for normal class
inheritance, and vala emits warnings if you don't do it correctly.

I'm not sure it's completely unintentional, Vala can be such an awkward
language at some times (but we still love it ;-)). See below.


This issue is actually a precursor to my real question, which I don't
think has come up before on this list exactly, although similar
threads have touched on it.

I really want to be able to define a class as implementing an
interface with default implementations of virtual methods, and have
subclasses of that class override the virtual methods. So:
[...]
But I suspect this is impossible with the way GObject is designed,
which would be a shame.
Nothing is impossible in Vala, things just happen to be weird ;-p

You won't believe the answer is so easy, I've tried many ways before
finding the correct answer (I've even written a long paragraph trying to
argue how it could be possible in GObject).

You just need to declare that your subclass implements the interface
(and of course remove the override keyword). So the following code:

interface Interface {
 public virtual void function () {
       print ("interface\n");
 }
}

class Class : Object, Interface {}

class Subclass : Class, Interface {
 public void function () {
  print ("subclass\n");
 }
}

var bc = new Class();
bc.function();

var sc = new Subclass();
sc.function();

prints:

interface
subclass

HTH,
Abderrahim



But see this is just a workaround. What I want is for the subclass to
inherit the interface and the interface implementation from the base
class, and override certain aspects. But what you have to do instead
is reimplement the interface, and override everything again. The two
are the same thing in these examples because they are so trivial. But
consider:

interface Interface {
    public virtual void virtual_function () {
        print ("interface - virtual\n");
    }
    public virtual void other_virtual_function () {
        print ("interface - other virtual\n");
    }
    public abstract void abstract_function ();
}

class Class : Object, Interface {
    public virtual void other_virtual_function () {
        print ("class - other virtual\n");
    }
    public void abstract_function () {
        print ("class - abstract\n");
    }
}

class Subclass : Class, Interface {
    public void virtual_function () {
        print ("subclass - virtual\n");
    }
}

void main () {
    var c = new Class ();
    c.virtual_function ();
    c.other_virtual_function ();
    c.abstract_function ();

    var s = new Subclass ();
    s.virtual_function ();
    s.other_virtual_function ();
    s.abstract_function ();
}

This outputs:

interface - virtual
class - other virtual
class - abstract
subclass - virtual
interface - other virtual
Segmentation fault


You see the subclass does not inherit the base class' implementation
of other_virtual_function, nor abstract_function for that matter.

Regards
James



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]