Mixins e mútiplas heranças

Como descrito antes, Vala enquanto é apoiado em C e GObjects, pode prover um mecanismo limitado de mútipla herança, ai adicionar métodos virtuais as interfaces. É possível adicionar alguns jeitos de definir implementação padrão a métodos em classes implementadoras das interfaces e permitir que classes derivadas sobreponham esses métodos.

Se você definir um método virtual em uma interface e implementar isso em uma classe, você não pode sobrepor o método da interface sem deixar a classe derivada incapaz de acessar a implementação padrão da interface. Considere o caso a seguir:

public interface Callable : GLib.Object {
   public abstract bool answering { get; protected set; }
   public abstract void answer ();
   public abstract bool hang ();
   public static bool default_hang (Callable call)
   {
      stdout.printf ("At Callable.hang()\n");
      call.answering = false;
      return true;
   }
}

public abstract class Caller : GLib.Object, Callable
{
   public bool answering { get; protected set; }
   public void answer ()
   {
     stdout.printf ("At Caller.answer()\n");
     answering = true;
     hang ();
   }
   public virtual bool hang () { return Callable.default_hang (this); }
}

public class TechPhone : Caller {
        public string number { get; set; }
}

public class Phone : Caller {
   public override bool hang () {
        stdout.printf ("At Phone.hang()\n");
        return false;
   }

   public static void main ()
   {
      var f = (Callable) new Phone ();
      f.answer ();
      if (f.hang ())
         stdout.printf("Hand done.\n");
      else
         stdout.printf("Hand Error!\n");

      var t = (Callable) new TechPhone ();
      t.answer ();
      if (t.hang ())
         stdout.printf("Tech Hand done.\n");
      else
         stdout.printf("Tech Hand Error!\n");
      stdout.printf("END\n");
   }
}

Nesse caso, nós definimos uma interface Callable com uma implementação padrão para abstract bool hang () chamada default_hang, ela pode ser um método static ou virtual. Então Caller é a classe base implementando Callable para as classes TechPhone e Phone, enquanto o método hang () da Caller usa a implementação padrão de Callable. TechPhone não faz nada e pega Caller como classe base, usando a implementação padrão do método, mas Phone sobrepõe Caller.hang () e isso faz com que ele usa sua própria implementação, permitindo sempre chama-lo mesmo se for convertido em um objeto Callable.

Implementação explícita de método

A implementação explicita de métodos de interface permite que sejam implementadas duas interfaces que tenham os mesmos métodos (não propriedades) com o mesmo nome.

Exemplo:

interface Foo {
 public abstract int m();
}

interface Bar {
 public abstract string m();
}

class Cls: Foo, Bar {
 public int Foo.m() {
  return 10;
 }

 public string Bar.m() {
  return "bar";
 }
}

void main () {
 var cls = new Cls ();
 message ("%d %s", ((Foo) cls).m(), ((Bar) cls).m());
}

A saída será 10 bar.

results matching ""

    No results matching ""