先来看看Java接口实现,先定义一个User类,用于传递对象值。
public class User {
String name;
String email;
public User(String name, String email){
this.name = name;
this.email = email;
}
}
再定义一个接口
public interface Notifier {
public void notifyForJava(User user);
}
下面编写一个类来实现这个接口。
public class UserImplementNotifier implements Notifier {
// implement Notifier接口,实现notityForJava方法
@Override
public void notifyForJava(User user) {
System.out.println("Sending User Email To " + user.name()+ "<" + user.email() + ">\n");
}
public static void main(String[] args) {
User user = new User("Bill", "bill@email.com");
Notifier userImplementNotifier = new UserImplementNotifier();
userImplementNotifier.notifyForJava(user);
}
}
下面再来看看Go如何进行接口实现的
import (
"fmt"
)
// 定义一个接口
type notifier interface {
notify()
}
type user struct {
name string
email string
}
// user实现接口方法
func (u *user) notify() {
fmt.Printf("Sending user email to %s<%s>\n",
u.name,
u.email)
}
func main() {
u := user{"Bill", "bill@email.com"}
// 这里使用的指针类型
sendNotification(&u)
}
// 注意这里,传入参数时notifier接口
func sendNotification(n notifier) {
n.notify()
}
对比两个实现,最主要的区别在于_接口实现_,在Java中是通过Class后面的implement来实现接口,必须实现接口中的方法。Go中的接口是用来定义行为的类型,是通过用户定义的类型实体类型
实现接口声明的方法的,在上面的例子中,定义了user这个实体类型,通过在func和notify中间添加实体类型来对接口方法进行func (u *user) notify()
实现,可以看到Go中对接口的实现在语法上是比较松散的,没有Java那么严格。
不知道大家注意到func (u *user) notify()
user前面有一个*
,调用时需要sendNotification(&u)
就是u前面需要&
,这里面用到方法集,方法集定义了接口的接收规则。有个规则需要知道的,就是
Methods Receivers | Values |
---|---|
(u user) | sendNotification(&u)和sendNotification(u) |
(u *user) | sendNotification(&u) |
什么意思呢? 就是接受者使用指针接收(u *user)
时,
func (u *user) notify() {
fmt.Printf("Sending user email to %s<%s>\n",
u.name,
u.email)
}
必须使用sendNotification(&u)
,u的指针进行传参。
如果是
func (u user) notify() {
fmt.Printf("Sending user email to %s<%s>\n",
u.name,
u.email)
}
使用sendNotification(&u)
和sendNotification(u)
都可以。
总结,Go中对接口的实现和Java有所不同,Java中必须通过implement来实现接口,必须实现接口中定义的方法(JDK1.7之前),而Go对接口的实现是定义_实体类型_,在要实现的接口前面添加实体类型,相对语法比较松散,没有被接口绑定,更加高级。