Please correct my vague understanding of interfaces

I’ve not used interfaces in any language before so I’m still trying to get my head around it. I’d appreciate some feedback and elaboration on my current understanding. I may be misunderstanding this completely! I am sometimes thinking this interface abstraction thing may be hiding details that might of been more clear had I called the methods directly. In my code below, the type Shaper interface looks like fluff to me. Anyway, here goes…

A type interface proxies the type and value of variables and their method calls.

A type interface declares a group of related method names and their signatures, such that when assignments are made or methods called, the correct method is used based on the receiver type.

A type interface usually has two or more methods. If only one method is declared then you might as well just call the method directly.

Here is a test program I wrote: This works even though there is no Perimeter method for Dim3 (of course, it is never called).

package main

import (
	"fmt"
)

type Shaper interface {
    Volume() float64
    Perimeter() float64
}

type Dim2 struct {
	x float64
	y float64
}

type Dim3 struct {
	x float64
	y float64
	z float64
}

func (d Dim2) Volume() float64 {
	return d.x * d.y
}

func (d Dim3) Volume() float64 {
	return d.x * d.y * d.z
}

func (s Dim2) Perimeter() float64 {
	return (s.x + s.y) * 2
}

func print(s Shaper) {
    fmt.Println("Shaper Perimeter :", s.Perimeter() )
}

func main() {
	a := Dim2{x : 2, y : 4}
	b := Dim3{x : 2, y : 4, z : 8}

	fmt.Println("Dim2 Volume :", a.Volume() )
	fmt.Println("Dim3 Volume :", b.Volume() )

    var s Shaper = a

    print( s )

}

It can run because you didn’t tell the compiler Dim3 is a Shaper variable with var _ Shaper = (*Dim3)(nil)

Interface is a define rule,it just define the requirement of being something.

Such as Driver ,we define like this.

   type Driver interface{
        Drive()
 }

We declar struct Human,which declare Drive,so that all the Human is Driver

  type Human struct{}
   func (h *Human) Drive(){ }

What if a Pig,It can also Drive.That means all the Pig is Driver too.

  type Pig struct{}
   func (h *Human) Drive(){ }

Interface is only Care whether the struct have functions it requres,not care who are they.
This is it’s most important feature

Besides you can easyily undersyand interface with Connection

 type Conn interface{
     Write()
    Send() 
}

Both TCP and UDP have Write and Send ,so they are Conn

There are many cases of single-method interfaces, e.g. io.Writer which has a single Write() method. The purpose of an interface is to enable polymorphism or “duck-typing”, where you don’t care what exact type you are getting but you need to make sure it has a certain set of methods. For example, you might be writing some kind of network library but you don’t care if it is a file, a network connection, or a piece of spaghetti, as long as you can write to it. On the other hand, if you know what type you are working with and that it will not be any other type, it is more efficient to call the method directly.

1 Like

When you think it’s a duck that can swim, then everything that has a swimming behavior is a duck. Interface usage is widespread in golang, which only allows developers to focus on the behavior itself, not the object.

You are using an abstract example that doesn’t solve any problem.

Let me simplify this topic: An interface allows your functions and variables to accept different types. This is the whole reason why interfaces exist.

Imagine you are creating a fantasy game and you want to create a function that calculates the damage of a creature passed as an argument to that function.

Without interfaces, you would have to write a separate function for each creature. Something like this:

func calculateDamage(dragon: Dragon)
func calculateDamage(orc: Orc)
func calculateDamage(troll: Troll)
func calculateDamage(dwarf: Dwarf)
func calculateDamage(elf: Elf)
// and so on for every creature in the game

Instead of that, you can create a common interface called Creature for each NPC in your game and instead write a single function that accepts any struct that implements this interface:

func calculateDamage(creature: Creature)
1 Like

Thank you, this is one of the better explanations.

It seems to me that, in some respects, strict typing and interfaces are at odds with each others.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.