implementing interfaces on classes that already have the interface members defined

lordofduct

Well-known member
Joined
Jun 24, 2010
Messages
71
Programming Experience
3-5
So say I define some interface, and that interface has members that need to be implemented under some idea, and I then implement this interface on a class that already has those members defined. How do I NOT receive errors about having to implement said members despite them already being implemented (because I didn't type the oh so ridiculous 'implements IMyInterface.foo').


For example say I have an interface that defines the event KeyPress, and then I have a custom Form that implements this interface of mine. It throws an error.

VB is the 5th language I've worked in that uses interfaces... and up until now they've all treated interfaces relatively the same. This is the first time I've seen this not allowed. What perplexes me more, is it IS allowed in other .Net languages. Just not VB.


Code example of what I'm talking about:

VB.NET:
using System;
using System.Windows.Forms;

namespace DylanTest1
{

    public partial class Form1 : Form, ITest
    {
        private ITest _obj;

        public Form1()
        {
            InitializeComponent();

            _obj = this;

            _obj.KeyPress += this.foo;
        }

        private void foo(Object sender, EventArgs e)
        {
            Console.WriteLine(_obj.Name);
        }
    }

    interface ITest
    {
        event KeyPressEventHandler KeyPress;

        string Name { get; set; }
    }
}

works fine in C#


VB.NET:
Imports System
Imports System.Windows.Forms

Public Class Form1 : Inherits Form : Implements ITest

    Private _obj As ITest

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

        _obj = Me

        AddHandler _obj.KeyPress, AddressOf Me.Foo
    End Sub

    Private Sub Foo(ByVal sender As Object, ByVal e As KeyPressEventArgs)
        Console.WriteLine(_obj.Name)
    End Sub
End Class


Public Interface ITest
    Event KeyPress As KeyPressEventHandler

    Property Name() As String
End Interface

fails in VB:

Error 1 Class 'Form1' must implement 'Event KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs)' for interface 'ITest'. I:\DylanDocs\Dylan\Documents\Visual Studio 2008\Projects\DylanVBTest1\DylanVBTest1\Form1.vb 4 49 DylanVBTest1

Error 2 Class 'Form1' must implement 'Property Name() As String' for interface 'ITest'. Implementing property must have matching 'ReadOnly' or 'WriteOnly' specifiers. I:\DylanDocs\Dylan\Documents\Visual Studio 2008\Projects\DylanVBTest1\DylanVBTest1\Form1.vb 4 49 DylanVBTest1
 
You have to add the 'ridiculous' Implements IMyInterface.foo instruction, that's how interface implementations are expressed in VB. In VB you can name members anything you want and it is not tied to the interface member name, but you have to 'explain' to compiler which implementation is bound to which interface. Usually you just write the 'class - implements' instruction and press enter to have IDE generate all members, but for existing members you have to map the Implements to correct member.
 
I can't say 'Implements IMyInterface.somemember', because the members of the class I want to be the implementors are in the base class (System.Windows.Forms.Control)... I can't go BACK to Control and modify the code, they're native classes. But I want the KeyPress and Name event (in this example that is) to be the members that serve as the contract.



Is it seriously this way in VB? You MUST verbosely state you are "implementing" something??? So handing a contract to a type that already performed the contract with out stating implements, can't receive said contract? That's bad design in my opinion.

I found this 2 year old article about it...

Implicitly implemented interfaces

and I have to agree that the idea is a much better way of doing it. Allow people to say 'implements IMyInterface.foo' which gives coders the chance to use a different name for the member (which for some reason vb coders oh so love this feature??? ok...). But allow the implicit at the same dang time for those who want to use interfaces for what they're supposed to be used for... defining contracts.
 
I can't say 'Implements IMyInterface.somemember', because the members of the class I want to be the implementors are in the base class (System.Windows.Forms.Control)... I can't go BACK to Control and modify the code, they're native classes. But I want the KeyPress and Name event (in this example that is) to be the members that serve as the contract.
It is your class that choose to implement this interface and thus your class that must provide all implementations, even if those implementations are just redirections to base functionality. If the base class implements the interface your inherited class may override those implementations, and does need not 'reimplement' the whole interface.
Is it seriously this way in VB? You MUST verbosely state you are "implementing" something??? So handing a contract to a type that already performed the contract with out stating implements, can't receive said contract? That's bad design in my opinion.
What if your class implements two different interfaces that happens to have two members with same name and signature, but should provide different implementations? Implicitly that would not be possible, explicitly with no name dependency for the implementation that is no problem.
But allow the implicit at the same dang time for those who want to use interfaces for what they're supposed to be used for... defining contracts.
It's not there yet.
 
It is your class that choose to implement this interface and thus your class that must provide all implementations, even if those implementations are just redirections to base functionality. If the base class implements the interface your inherited class may override those implementations, and does need not 'reimplement' the whole interface.

I should be able to have the choice on way or the other. It's my class that is implementing the interface... and there is already a member that implements it... I should have the choice to pick the already existing member, or define a new one. Implicit OR explicit.

What if your class implements two different interfaces that happens to have two members with same name and signature, but should provide different implementations? Implicitly that would not be possible, explicitly with no name dependency for the implementation that is no problem.

In this case, use explicit... in others use implicit.

Interfaces are meant for defining contracts that the interface of a class must follow (the shell of the class or externalized members).

This extra explicit name change way of implementing an interface adds some interesting new features. But gaining this added feature (that interface wasn't originally defined for) by chopping off the original intent of Interface is, IMO, stupid.

That's like chopping off your left leg, so you can have a stronger right leg so you can run faster, forgetting that with out the left leg you can't run period!

Keep the implicit method as well... now you still got your left leg AND a super strong right leg. Win win.

It's not there yet.

that's sad... and as the article I posted... it's something that has been floating around for a couple years now. It shouldn't be that difficult to put in... they had to take the extra steps to put in this verbose explicit ONLY way of implementing interfaces. I find that ridiculous. Is it wrong of me to find that ridiculous??? no, it certainly isn't...


my biggest beef is the fact that other .Net languages like C# already boast this explicit AND implicit capabilities... and has for a while. VB should catch up dang it. It's not like something that VB just happens to do differently (like the interface for adding and removing events)... it straight up lacks this capability.

I found one hacky method of getting around it. But dang is it hacky!

VB.NET:
Imports System
Imports System.Windows.Forms

Public Class Form1 : Inherits Form : Implements ITest

    Private _obj As ITest

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

        _obj = Me

        AddHandler _obj.Click, AddressOf Me.Foo
    End Sub



#Region "ITest Interface"
    Private Event ClickImp As EventHandler Implements ITest.Click

    Private Sub ClickReaddress(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Click
        Console.WriteLine(">> Readdressing KeyPress")

        RaiseEvent ClickImp(sender, e)
    End Sub

    Private Property NameImp() As String Implements ITest.Name
        Get
            Return Me.Name
        End Get
        Set(ByVal value As String)
            Me.Name = value
        End Set
    End Property
#End Region



    Private Sub Foo(ByVal sender As Object, ByVal e As EventArgs)
        Console.WriteLine(_obj.Name)
    End Sub


End Class


Public Interface ITest
    Event Click As EventHandler

    Property Name() As String
End Interface
 
Last edited:
Back
Top