what's the difference between Golang and Java about interface?

1,741 views
Skip to first unread message

Fei Ding

unread,
Oct 8, 2016, 9:14:34 AM10/8/16
to golang-nuts

Recently I've been asked a question which is, what's the difference between Golang and Java about interface?


I know there are some 'syntax-sugar level' differences, what I am interested is anything beneath the ground, like how does Golang and Java implement interface? What's the biggest difference? Which one is more efficient? Why?


Could anyone post blog links or source code about this topic? The only code I can find is in src/runtime/iface.go, but I cannot understand it or get anything useful by myself yet. Source code is better.


Thanks.

Pietro Gagliardi

unread,
Oct 8, 2016, 10:39:23 AM10/8/16
to Fei Ding, golang-nuts
The most obvious difference is that Go doesn't have the implements keyword. All you have to do to implement an interface is implement the interface's methods, and the Go compiler will take care of the rest.

This rule leads to the empty interface, interface{}. This interface requires no methods to be satisfied, and as such is satisfied by all types, including the builtin types such as int64.

Go interfaces can be satisfied by any kind of type, not just struct types.

type MySpecialInt int
func (m MySpecialInt) String() string {
return fmt.Sprintf("Hello! I'm %d!", int(m))
}
// MySpecialInt implements fmt.Stringer, so printing it with fmt functions will use the String() method

In Go, you do not have to predeclare your interface types;

func x(y interface{ T() }) { y.T() }

is valid.

Go does not have surrounding types, so the rules about having an interface in a Java class mean nothing to Go. This is only really relevant in one place: In Java, if you have an interface method marked private, only the surrounding class can implement that specific method, not the entire package. In Go, the entire package is able to implement an unexported method in an interface, but other packages cannot:

package a
type Y interface { q() }

package b
type X int
func (X) q() { ... } // X does NOT implement a.Y!

However, types in other packages CAN satisfy unexported interfaces:

package a
type y interface { Q() }

package b
type X int
func (X) Q() { ... } // X DOES implement a.y

Go does not have generic types, protected inheritance, static members, abstract types, final members, or strictfp, so those annotations in Java interfaces are unavailable. (In Go's case, there is *only* strictfp; the specification implies in lots of places that IEEE 754 is required, though looking at it again I'm not sure if a superset of IEEE 754 is acceptable or not...)

Go interfaces may only specify methods; Java interfaces may also specify fields and nested types. (This makes sense; Go interfaces can apply to any type, and only structs have "fields", and Go does not have nested types.)

Java interfaces can provide a default implementation for methods that an implementing class may choose not to override. Go interfaces cannot.

Go does not have the same types of annotations that Java has, so @interface is meaningless. For details on Go's closest approximation, see struct tags.

Go does not have functional interfaces or interface literals.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jan Mercl

unread,
Oct 8, 2016, 11:25:26 AM10/8/16
to Pietro Gagliardi, Fei Ding, golang-nuts


On Sat, Oct 8, 2016, 16:39 Pietro Gagliardi <and...@lostsig.net> wrote:


Go does not have functional interfaces or interface literals.

I don't know what is meant by 'functional interfaces' but Go definitely supports interface literals.

--

-j

Pietro Gagliardi

unread,
Oct 8, 2016, 11:31:27 AM10/8/16
to Jan Mercl, Fei Ding, golang-nuts
In Java, if an interface contains exactly one method, and that method is not already part of java.lang.Object, the syntax

Interface i = (arguments) -> {
code
};

will make an object i of that interface type with the given closure as the method body. This interface is called a functional interface.

Pre-Java 8, the same thing could be done with

Interface i = new Interface() {
public void method() {
code
}
};

These interface literals are different from Go's interface literals.

Henrik Johansson

unread,
Oct 8, 2016, 12:05:31 PM10/8/16
to Pietro Gagliardi, Jan Mercl, Fei Ding, golang-nuts

But that is just syntactic sugar around the fact that Java does not have first class functions. At least not in the sense Go does.

Pietro Gagliardi

unread,
Oct 8, 2016, 4:17:35 PM10/8/16
to Henrik Johansson, Jan Mercl, Fei Ding, golang-nuts
Of course. And in Go you would write code in a way that would avoid the need for such constructs in the first place.

Aside: is there a way to get El Capitan Mail.app to play nice with Google Groups?

T L

unread,
Oct 9, 2016, 10:37:38 AM10/9/16
to golang-nuts

You can make a concrete type in std lib implement your custom interface:

package main

import "fmt"
import "time"

type I interface {
    IsZero() bool
}

func main(){
    var i I = time.Now()
    fmt.Println(i.IsZero()) // false
}

 

T L

unread,
Oct 9, 2016, 10:42:12 AM10/9/16
to golang-nuts
In golang, if a concrete type embeds an interface type, the concrete type must implement this interface type.

package main


type I interface {
    IsZero() bool
}

type T struct {
    I
}

var i I = T{} // implemention assertion ok

func main(){
}

On Saturday, October 8, 2016 at 9:14:34 PM UTC+8, Fei Ding wrote:
Message has been deleted

Haddock

unread,
Oct 10, 2016, 5:22:29 PM10/10/16
to golang-nuts, 0xj...@gmail.com, fdin...@gmail.com


Am Samstag, 8. Oktober 2016 17:31:27 UTC+2 schrieb Pietro Gagliardi (andlabs):
In Java, if an interface contains exactly one method, and that method is not already part of java.lang.Object, the syntax

Interface i = (arguments) -> {
code
};

will make an object i of that interface type with the given closure as the method body. This interface is called a functional interface.

Pre-Java 8, the same thing could be done with

Interface i = new Interface() {
public void method() {
code
}
};


The number of methods in a Java interface is of course arbitrary and not restricted to a single one. The first code sample above shows a Java8 lamda expression which inevitably consists of the lambda function itself. Lambdas in Java8 implement a variety of interfaces, but this does not mean that interfaces in Java must only contain one method.

The biggest difference is that a "class" or struct in Go implicitly implements an interface once it contains all the methods defined in some Go interface. In Java a a class must explicitly implement an interface.

As what lambdas or closures are concerned Go supports full-fledges closures, which means support for non-local returns, variables outside the closure are writeable. This is not the case in Java and in Java you cannot throw checked exceptions from within a closure. These limitations in Java are all due to (binary) backwards compatibility and limitations of the JVM (e.g. non-local returns).

gott...@gmail.com

unread,
Oct 10, 2016, 8:05:38 PM10/10/16
to golang-nuts
An interesting aside about Java Interfaces that most people don't know is that you can have an empty Interface without methods or members and then declare different objects as implementing that empty interface. The purpose of this in Java is different then in Golang but it allows arbitrary instance of classes (objects) to be passed around without using Object as the class. I found this out while looking at Koopla source code and it is a handy trick for Java programmers to know. Sorry, this hint isn't really about Golang.

Henrik Johansson

unread,
Oct 10, 2016, 8:28:51 PM10/10/16
to gott...@gmail.com, golang-nuts

Yet a notable such marker interface Serializable is known by almost all Java developers ;)


--
Reply all
Reply to author
Forward
0 new messages