我如何翻译这个Java界面& Golang的继承结构?

时间:2018-06-15 05:37:08

标签: java inheritance go

是否有可能将使用接口和继承的Java结构重写为惯用的Golang方式?

这不是超级复杂的Java代码,但它显示了类继承的强度,但我想尝试在Go中以某种方式实现相同的结果

Java代码:

首先是一个类接口。

public interface WebEntry {
    String perform(ConnectionData connectionData, SessionData sessionData) throws Exception;
}

某处有一个网络条目列表WebEntry

List<WebEntry> webEntries = new ArrayList<>();
webEntries.add( new SavePasswordWebEntry() );

实现UserLoggedInWebEntry

的抽象类WebEntry
public abstract class UserLoggedInWebEntry implements WebEntry {

    @Override
    public String perform(ConnectionData connectionData, SessionData sessionData) throws Exception {

        // THIS IS THE LOGIC I DO NOT WANT TO DUPLICATE, HENCE ITS USING CLASS INHERITANCE
        ...

        return userPerform(User user);

    }

    protected abstract String userPerform(User user) throws Exception;

}

通过使用类继承,我们可以创建一个仍然表现为UserLoggedInWebEntry的{​​{1}},但每次我们想要“用户登录”时我们都不需要复制WebEntry逻辑在网络条目“实例:

...

所以重点是,由于它使用类继承,开发人员只需实现public class SavePasswordWebEntry extends UserLoggedInWebEntry { @Override protected String userPerform(User user) throws Exception { ... } } 而不重复String userPerform(User user)...的逻辑。

这是否有可能在Golang实现?如果是这样,它会是什么样子?

3 个答案:

答案 0 :(得分:0)

我想出了如何自己实现同样的事情,即使我喜欢&#34; Just learn Go&#34;我得到的答案。

通过创建一个包含userLoggedInWebEntry函数签名但仍返回WebEntryUserLoggedIn函数签名的包装函数WebEntry来解决此问题。

通过让开发人员只实现func( user User ) string并且userLoggedInWebEntry中的逻辑不重复

,它实现了与上面的Java继承代码相同的功能。

https://play.golang.org/p/adrk46YFIl8

package main

import (
    "fmt"
)

type ConnectionData string
type SessionData string
type User string

type WebEntry func(connectionData ConnectionData, sessionData SessionData) string
type WebEntryUserLoggedIn func( user User ) string

func main() {
    var webentries []WebEntry
    webentries = append( webentries, userLoggedInWebEntry(SavePasswordWebEntry) )

    // Test the invocation
    fmt.Println( webentries[0]("ConnectionData", "SessionData") )
}


func userLoggedInWebEntry( webEntry WebEntryUserLoggedIn ) WebEntry {

    return func(connectionData ConnectionData, sessionData SessionData) string {
        // // THIS IS THE LOGIC I DO NOT WANT TO DUPLICATE, HENCE ITS USING CLASS INHERITANCE
        var user User = "John"
        return webEntry( user )
    } 

}


func SavePasswordWebEntry( user User ) string {
    return fmt.Sprintf("user is %s", user )
}

答案 1 :(得分:-1)

也许是这样的?

type WebEntry interface {
    Perform() string
}

type SomeWebEntry struct {
}

func (_ *SomeWebEntry) Perform() string {
    return "SomeWebEntry"
}

type OtherWebEntry struct {
    SomeWebEntry
}

func (this *OtherWebEntry) OtherPerform() string {
    return this.Perform() + "OtherWebEntry"
}

func main() {
    webEntries := []WebEntry{&SomeWebEntry{},&OtherWebEntry{}}
    for _, v := range webEntries {
        fmt.Println(v.Perform())
    }
    fmt.Println("-")
    fmt.Println(webEntries[1].(*OtherWebEntry).OtherPerform())
}

您可以使用名为embedding的功能。

答案 2 :(得分:-1)

在这里你看。我不知道我是否理解正确。

package main

import (
    "fmt"
)

type ConnectionData struct{}
type SessionData struct{}

type WebEntry interface {
    Perform(c ConnectionData, s SessionData) (string, error)
}

type UserLoggedInWebEntry struct {
}

func (u *UserLoggedInWebEntry) Perform(c ConnectionData, s SessionData) (string, error) {
    return u.UserPerform(c, s)
}

func (u *UserLoggedInWebEntry) UserPerform(c ConnectionData, s SessionData) (string, error) {
    return "UserLoggedInWebEntry UserPerform", nil
}

type SavePasswordWebEntry struct {
    UserLoggedInWebEntry
}

func (sp *SavePasswordWebEntry) Perform(c ConnectionData, s SessionData) (string, error) {
    return "SavePasswordWebEntry Perform", nil
}

func main() {
    webEntries := make([]WebEntry,0)
    webEntries = append(webEntries, new(SavePasswordWebEntry))
    for _, we := range webEntries {
        fmt.Println(we.Perform(ConnectionData{},SessionData{}))
    }
}

Playground