是否有更好的方法来实现继承? (在c#中,我们使用Abstract类和Interfaces实现类似的行为)。请参考以下代码以了解问题。
我尝试在Go中使用接口,但无法访问struct的数据字段。
type Vehicle struct {
Id int
Name string
VehicleType VehicleTypeBase
}
type VehicleTypeBase struct {
Id int
Name string
Milage int
}
type VehicleTypeSedan struct {
VehicleTypeBase
IsABSEnabled bool
}
type VehicleTypeHatchback struct {
VehicleTypeBase
Is4WheelDriveEnabled bool
}
func main() {
var veh Vehicle
veh = Vehicle{
Id: 1,
Name: "Zeep Compass",
VehicleType: VehicleTypeSedan{
Id: 1,
Name: "Sedan",
Milage: 13,
IsABSEnabled: true,
},
}
}
// Above initialization gives error. Here, I would like to understand that how // to achieve inheritance using base class
// in Golang. Is there a way to solve this situation in Go??
错误消息是:
。\ main.go:40:3:在字段值中不能使用VehicleTypeSedan文字(类型VehicleTypeSedan)作为VehicleTypeBase类型
答案 0 :(得分:0)
结构嵌入是lang首选的方式。构想比继承更好。
https://golang.org/doc/effective_go.html#embedding
您应该为Vehicle声明一个接口,并且所有Vehicle都实现该接口。
这是设计级的问题,而不仅仅是解决错误。由于尚不清楚您将如何使用和处理车辆。我会做一些假设。
通过嵌入方式应将可重用结构嵌入特定结构中。
type VehicleTypeGeneral struct {
Id int
Name string
Milage int
}
//Embed VehicleTypeGeneral
type VehicleTypeHatchback struct {
VehicleTypeGeneral
Is4WheelDriveEnabled bool
}
如果我们创建VehicleTypeHatchback
的实例vh,那么我们可以访问VehicleTypeHatchback
的字段以及VehicleTypeGeneral
和vh.Is4WheelDriveEnabled
如果VehicleTypeGeneral
实现的接口类似于Vehicle
接口,那么VehicleTypeHatchback
也会实现该接口。您可以通过实现这些方法来覆盖。
我在processSpecificVehicle
函数中添加了类型检查示例。但是这些事情会减慢执行速度。而是尝试使用processVehicle
和processAbsVehicle
接口也不应该有太多方法。一个或两个就足够了,否则违反了接口隔离原则。保持界面简短有意义,并根据界面使用者的需求进行设计。
完整的示例并带有以下假设:
package main
import "fmt"
type Vehicle interface {
GetId() int
GetName() string
}
type AbsVehicle interface {
IsAbsEnabled() bool
}
type VehicleTypeGeneral struct {
Id int
Name string
Milage int
}
func (v *VehicleTypeGeneral) GetId() int{
return v.Id
}
func (v *VehicleTypeGeneral) GetName() string{
return v.Name
}
type VehicleTypeSedan struct {
VehicleTypeGeneral
IsABSEnabled bool
}
func(vs *VehicleTypeSedan) IsAbsEnabled() bool {
return vs.IsABSEnabled
}
type VehicleTypeHatchback struct {
VehicleTypeGeneral
Is4WheelDriveEnabled bool
}
func main() {
println("Hello")
var vehicle = VehicleTypeSedan{IsABSEnabled: true, VehicleTypeGeneral: VehicleTypeGeneral{Id:1001,Name:"Sedan 1", Milage:12}}
processVehicle(&vehicle)
processAbsVehicle(&vehicle)
processSpecificVehicle(&vehicle)
processSedan(&vehicle)
}
func processVehicle(vehicle Vehicle){
println(vehicle.GetId())
println(vehicle.GetName())
}
func processAbsVehicle(vehicle AbsVehicle){
println(vehicle.IsAbsEnabled())
}
func processSpecificVehicle(vehicle Vehicle){
switch v := vehicle.(type) {
case *VehicleTypeSedan:
fmt.Printf("Its a sedan %v with ABS %v ", v.GetName(), v.IsAbsEnabled())
case *VehicleTypeHatchback:
fmt.Printf("Its a VehicleTypeHatchback %v", v.GetName())
default:
fmt.Printf("Its a Vehicle")
}
}
func processSedan(vs *VehicleTypeSedan){
println("\nprocess sedan")
println(vs.VehicleTypeGeneral.Name)
println(vs.IsABSEnabled)
}
答案 1 :(得分:-1)
可以工作!
type Vehicle struct {
Id int
Name string
VehicleType VehicleTypeInterface
}
type VehicleTypeInterface interface{}
type VehicleTypeBase struct {
Id int
Name string
Milage int
}
type VehicleTypeSedan struct {
VehicleTypeBase
IsABSEnabled bool
}
type VehicleTypeHatchback struct {
VehicleTypeBase
Is4WheelDriveEnabled bool
}
func main() {
var veh Vehicle
veh = Vehicle{
Id: 1,
Name: "Zeep Compass",
VehicleType: VehicleTypeSedan{
VehicleTypeBase: VehicleTypeBase{
Id: 3,
Name: "Sedan",
Milage: 13,
},
IsABSEnabled: true,
},
}
fmt.Printf("%+v", veh)
}