MST

星途 面试题库

面试题:Go接口声明边界之接口嵌套与方法集覆盖

假设有两个接口 `InterfaceA` 和 `InterfaceB`,`InterfaceB` 嵌套了 `InterfaceA`。定义一个结构体 `StructC` 实现 `InterfaceB`。现在,若 `StructC` 对 `InterfaceA` 中的某个方法进行了特殊实现,而在实际使用中需要区分调用 `InterfaceA` 原始定义的方法和 `StructC` 特殊实现的方法,应该如何设计和处理?请给出具体的代码示例,并阐述涉及到的接口声明边界情况的原理。
33.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

代码示例(以Go语言为例)

package main

import "fmt"

// InterfaceA 定义接口A
type InterfaceA interface {
    MethodA()
}

// InterfaceB 定义接口B,嵌套InterfaceA
type InterfaceB interface {
    InterfaceA
    MethodB()
}

// StructC 结构体实现InterfaceB
type StructC struct{}

// MethodA 特殊实现InterfaceA的MethodA
func (s StructC) MethodA() {
    fmt.Println("StructC's special implementation of MethodA")
}

// MethodB 实现InterfaceB的MethodB
func (s StructC) MethodB() {
    fmt.Println("MethodB implementation")
}

// 定义一个包装类型,用于调用InterfaceA原始定义的方法
type InterfaceAWrapper struct {
    InterfaceA
}

// MethodA 调用原始InterfaceA的MethodA
func (w InterfaceAWrapper) MethodA() {
    w.InterfaceA.MethodA()
}

func main() {
    var b InterfaceB = StructC{}
    b.MethodA() // 调用StructC特殊实现的MethodA

    var a InterfaceA = InterfaceAWrapper{b}
    a.MethodA() // 调用InterfaceA原始定义的方法,这里实际上是通过包装类型间接调用
}

接口声明边界情况的原理

  1. 接口嵌套:在Go语言中,当一个接口(如 InterfaceB)嵌套另一个接口(如 InterfaceA)时,实现 InterfaceB 的类型(如 StructC)必须实现 InterfaceAInterfaceB 中定义的所有方法。
  2. 方法重写:当 StructCInterfaceA 中的 MethodA 进行特殊实现时,在通过 InterfaceB 类型的变量调用 MethodA 时,会调用 StructC 特殊实现的版本。
  3. 区分调用:为了调用 InterfaceA 原始定义的方法,我们创建了一个包装类型 InterfaceAWrapper。这个包装类型持有一个 InterfaceA 类型的实例,并且重新定义了 MethodA 方法,在该方法中调用持有的 InterfaceA 实例的 MethodA 方法。这样,通过将 InterfaceB 类型的实例包装成 InterfaceAWrapper 类型,就可以调用到 InterfaceA 原始定义的方法。这种设计方式利用了Go语言接口的组合特性以及类型断言等概念,巧妙地解决了区分调用不同版本方法的问题。