面试题答案
一键面试分析
- 将
S
实例赋值给A
接口类型变量:S
未完全实现A
接口所有方法,所以不能赋值给A
接口类型变量,否则编译报错。
- 将
S
实例赋值给B
接口类型变量:S
实现了B
接口部分方法,所以可以赋值给B
接口类型变量。此时方法集为S
所实现的B
接口的那些方法。
- 将
T
实例赋值给A
接口类型变量:T
完全实现了B
接口,而B
嵌入了A
,所以T
也完全实现了A
接口。可以赋值给A
接口类型变量,方法集为A
接口的所有方法。
- 将
T
实例赋值给B
接口类型变量:- 可以赋值给
B
接口类型变量,方法集为B
接口的所有方法(包括嵌入的A
接口的方法)。
- 可以赋值给
代码示例(以 Go 语言为例)
package main
import "fmt"
// A 接口
type A interface {
MethodA()
}
// B 接口,嵌入 A 接口
type B interface {
A
MethodB()
}
// S 结构体,实现 B 接口部分方法
type S struct{}
func (s S) MethodB() {
fmt.Println("S.MethodB")
}
// T 结构体,完全实现 B 接口
type T struct{}
func (t T) MethodA() {
fmt.Println("T.MethodA")
}
func (t T) MethodB() {
fmt.Println("T.MethodB")
}
func main() {
// 尝试将 S 实例赋值给 A 接口类型变量,编译报错
// var a1 A = S{}
// 将 S 实例赋值给 B 接口类型变量
var b1 B = S{}
b1.MethodB()
// 将 T 实例赋值给 A 接口类型变量
var a2 A = T{}
a2.MethodA()
// 将 T 实例赋值给 B 接口类型变量
var b2 B = T{}
b2.MethodA()
b2.MethodB()
}
上述代码中:
- 注释掉的
var a1 A = S{}
会导致编译错误,因为S
未完全实现A
接口。 b1
为B
接口类型,指向S
实例,只能调用S
实现的MethodB
方法。a2
为A
接口类型,指向T
实例,可以调用T
实现的MethodA
方法。b2
为B
接口类型,指向T
实例,可以调用T
实现的MethodA
和MethodB
方法。