1

I'm a Java programmer, learning to program in Go. So far I really like the language. A LOT more than Java.

But there's one thing I'm a bit confused about. Java has interfaces because classes can inherit only from one class. Since Go allows multiple inheritance, what's the point of interfaces?

tldr
  • 11,924
  • 15
  • 75
  • 120
  • 1
    In my humble opinion, the answer to http://stackoverflow.com/questions/8531292/why-use-interfaces-multiple-inheritance-vs-interfaces-benefits-of-interfaces also applies here. – kush Aug 04 '13 at 23:18
  • Interfaces and multiple inheritance are related but only tangentially. Java's interfaces are not a substitute for multiple inheritance. Interfaces allow you to separate contract from implementation. Multiple inheritance has limited uses but causes more trouble and non-intuitive, hard-to-debug problems than it's worth, IMHO. – Jim Garrison Aug 05 '13 at 00:10
  • @JimGarrison, could you elaborate? Interfaces just tell 'what' to do, whereas with inheritance you also get information about 'how' to do it, with the option of overriding that behavior. How can inheritance cause trouble, and in what scenarios would interfaces be superior. An example would really help! – tldr Aug 05 '13 at 00:14
  • A lot of work has gone into workarounds for [the diamond inheritance problem](http://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem). Java avoids this altogether. A full treatise on the difference between interfaces and inheritance would take more space than is available on SO. – Jim Garrison Aug 05 '13 at 02:43
  • Completely agree with you on that. Java avoids multiple inheritance, and needs interfaces because of that. Go enables multiple inheritance by making you override the conflicting methods. My question was what purpose interfaces serve in this scenario. Turns out it's duck typing. I am adding an answer for the same – tldr Aug 05 '13 at 03:24
  • There is no inheritance in OOP meaning in Go. – I159 Nov 04 '16 at 09:35
  • What's the point of interfaces? Decouple code. See https://stackoverflow.com/a/62297796/12817546. Call a method “dynamically”. See https://stackoverflow.com/a/62336440/12817546. Access a Go package. See https://stackoverflow.com/a/62278078/12817546. Assign any value to a variable. See https://stackoverflow.com/a/62337836/12817546. –  Jul 10 '20 at 09:59

4 Answers4

12

Polymorphism

Interfaces enable functions to have a 'placeholder' parameter which can take different structs as an argument. For example, if structs Man, Woman, Child implement interface Human, then a method with the parameter Human can take any of the structs Man, Woman, Child as an argument. Hence, the interface parameter can 'morph' into any struct passed as an argument as long as it implements all functions defined in the interface.

This is important because interfaces are the only way of achieving Polymorphism in Go, since it doesn't have inheritance. So if Man 'extended' Human (by having it as an anonymous field), any method that used Human as an argument, would not be able to take Man as an argument.

My confusion stemmed from the fact that inheritance is also a way of achieving Polymorphism in Java, and I assumed that was the case here as well. I stand corrected!

tldr
  • 11,924
  • 15
  • 75
  • 120
9

Interfaces in Go are very different from interfaces in Java.

In Java a class has to formally agree to implement an interface:

public class Foo implements iFoo

In Go a user type implements an interface by simply doing so.

A function or property can then define what is expected:

func DoSomething(r io.Reader) {
    buf := make([]byte, 128)
    n, err := r.Read(buf)
    ...
}

The DoSomething function can be passed anything that implements the Read function found in the io.Reader interface, without the thing knowing or caring about the interface. It is the responsibility of the caller to make sure it is passing in something that implements the interface. This is checked at compile time.

We can take this a step further. We can define our own interface:

type MyInterface interface {
    io.Reader // Include Reader interface
    Seek(int) error // Include my own function
}
func DoSomething(r MyInterface) {
    buf := make([]byte, 128)
    n, err := r.Read(buf)
    ...
}

Go is also different in that it doesn't have a class or object type. Any user declared type, whether it be based on an integer, string, struct, array, slice, channel, etc. can have methods attached to it.

Go also doesn't have typical class-like inheritance you're normally used to, but it does have a couple of things that are pretty close.

Redeclared type:

type Num int

func (n Num) Print() {
    print(n)
}

type Number Num

func (n Number) Print() {
    Num(n).Print()
}

Anonymous fields:

type Foo struct {
    sync.Mutex
}

func main() {
    f := Foo{}
    f.Lock()
    // ...
    f.Unlock()
}
Jay Taylor
  • 13,185
  • 11
  • 60
  • 85
Luke
  • 13,678
  • 7
  • 45
  • 79
1

If supertype X is an interface, whoever is maintaining the code knows at once that it has no method implementations. If supertype Y is an abstract class, whoever is maintaining the code has to check whether there are method implementations. So it's a documentation/maintenance/readability thing.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
0

Classes can inherit and implement from multiple class files.

Unless I misinterpreted:

public class MyClass extends MySuperClass implements MyInterface, MySecondInterface

The point of interfaces is to allow for a completely abstract class. So abstract that there isn't a single method defined. I would use an interface when I need to create several abstract classes with the same basic structure. I would then be able to create instances of classes which extend the abstract class, which in turn would implement the interface.

This is done with the interface java.util.Collection and some classes like java.util.ArrayList and java.util.Stack implement that interface. This way you can store all kinds of lists' items in a Collection. This is why ArrayList has a method to addAll(Collection<? extends E> c).

You could say it is like being backwards compatible with simpler objects.

John Starich
  • 619
  • 11
  • 15