Google Go中抽象类/方法(Java)的等价性

时间:2014-06-15 18:01:37

标签: java interface go static-methods abstract

我是Go的新手,我想知道如何实现类似于抽象类的结构& Java中的方法。在Java中,我执行以下操作:

abstract class A{

 static method1(){
  ...
  method2();
  ...
 }

 abstract method2();

}

class B extends A{

 method2(){
  ...
 }

}

class C extends A{

 method2(){
  ...
 }

}

我了解接口和结构。我可以构建一个接口,然后构建一个struct来实现method1。但是方法2怎么样? 我知道我可以在另一个接口中嵌入一个接口,并将结构作为另一个结构的字段嵌入。但我没有看到用这些方法实现我的结构的方法。

我看到的唯一解决方案是在B类和C类中实现method1。还有另外一种方法吗?

注意:当然,在我的情况下,它不仅仅是一种方法。此外,我还有一个抽象类的层次结构,并且不想将所有内容都移到子类中。

我在互联网上找到的例子主要是每个界面只有一种方法。如果你们其中一个人能给我一个提示,那就太棒了!感谢。

5 个答案:

答案 0 :(得分:9)

您可以使用复合接口,例如io包:

http://golang.org/src/pkg/io/io.go?s=2987:3047#L57

type Reader interface {
    Read(p []byte) (n int, err error)
}
type Writer interface {
    Write(p []byte) (n int, err error)
}

type ReadWriter interface {
    Reader
    Writer
}

作为旁注,不要尝试使用go实现java代码,尝试学习Go Way

答案 1 :(得分:7)

由于Go在OOP意义上没有static方法,因此您经常会看到这些类型的方法被实现为包级别函数:

package mypackage

func() Method1() { ... } // Below I will call it Function instead

这样的包级别函数然后将接口作为参数。在这种情况下,您的代码看起来像这样:

package main

import "fmt"

type Methoder interface {
    Method()
}

func Function(m Methoder) {
    m.Method()
}

type StructB struct{}

func (s *StructB) Method() { fmt.Println("StructB") }

type StructC struct{} // You can do some "inheritance" by embedding a base struct

func (s *StructC) Method() { fmt.Println("StructC") }

func main() {    
    b := &StructB{}
    Function(b)    
}

<强>输出:

StructB

答案 2 :(得分:2)

这是我实现抽象类的方法,避免遇到循环引用和维护良好的工厂模式。

让我们假设我们的组件

具有以下包结构
component
  base
    types.go
    abstract.go
  impl1
    impl.go
  impl2
    impl.go
  types.go
  factory.go

定义组件的定义,在此示例中将在此处定义:

<强>组件/ types.go

package component

type IComponent interface{
    B() int
    A() int
    Sum() int
    Average() int
}

现在让我们假设我们要创建一个仅实现 Sum Average 的抽象类,但在这个抽象实现中我们希望能够访问使用已实施的 A B

返回的值

为实现这一目标,我们应该为抽象实现的抽象成员定义另一个接口

<强>组件/碱/ types.go

package base

type IAbstractComponentMembers {
    A() int
    B() int
}

然后我们可以继续实施抽象&#34;类&#34;

<强>组件/碱/ abstract.go

package base

type AbstractComponent struct {
    IAbstractComponentsMember
}

func (a *AbstractComponent) Sum() int {
    return a.A() + a.B()
}

func (a *AbstractComponent) Average() int {
    return a.Sum() / 2
}

现在我们继续实施

component / impl1 / impl.go //为 impl2

提供类似的功能
package impl1

type ComponentImpl1 struct {
    base.AbstractComponent
}

func (c *ComponentImpl1) A() int {
    return 2
}

func (c *ComponentImpl1) A() int {
    return 4
}

// Here is how we would build this component
func New() *ComponentImpl1 {
    impl1 := &ComponentImpl1{}
    abs:=&base.AbstractComponent{
        IAbstractComponentsMember: impl1,
    }
    impl1.AbstractComponent = abs
    return impl1
}

我们为此使用单独的接口而不是使用相同的IComponent接口的原因是因为如果我们在这种情况下使用相同的接口,如果我们在 impl中导入 base 包* 使用摘要&#34; class&#34;我们还在组件包中导入了 impl * 包,因此工厂可以注册它们,我们会找到循环引用。

所以我们可以有像这样的工厂实现

<强>组件/ factory.go

package component

// Default component implementation to use
const defaultName = "impl1"
var instance *Factory

type Factory struct {
    // Map of constructors for the components
    ctors map[string]func() IComponent
}

func (f *factory) New() IComponent {
    ret, _ := f.Create(defaultName)
    return ret
}

func (f *factory) Create(name string) (IComponent, error) {
    ctor, ok := f.ctors[name]
    if !ok {
        return nil, errors.New("component not found")
    }
    return ctor(), nil
}

func (f *factory) Register(name string, constructor func() IComponent) {
    f.ctors[name] = constructor
}

func Factory() *Factory {
    if instance == nil {
        instance = &factory{ctors: map[string]func() IComponent{}}
    }
    return instance
}

// Here we register the implementations in the factory
func init() {
    Factory().Register("impl1", func() IComponent { return impl1.New() })
    Factory().Register("impl2", func() IComponent { return impl2.New() })
}

答案 3 :(得分:1)

GO LANG OO继承自Small Talk,而不是像C ++这样的Simula,而不是继承自C ++的OO概念的Java。记住这一点,GO OO将变得清晰明显。

因此。 GO中没有类的概念。只是对象,发送和接收消息。 GO接口可以在概念上解释为消息集合。

GO类型不“实现”接口,它们只是实现属于某个接口的消息。

重复:没有类,没有抽象基类,因此Go中没有“基于类的设计”(如在Small Talk中)。

难怪尝试在GO中实施ABC是一个烂摊子,正如我们在这里清楚看到的那样。

答案 4 :(得分:0)

除非你从method1中删除静态关键字,否则你要问的例子不能用Java编译,所以Java中正确的抽象类就像这样。

<xsl:template match="Products/Product/citem[type=../FavType]/color" >
    <xsl:copy>
        <xsl:variable name="prodId" select="../../@prodId"/>
        <xsl:for-each select="$doc1">
            <xsl:value-of select="key('k1', $prodId)/Item/@colorDef"/>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

要提供相同的语言,您必须按以下方式使用界面:Go Playground

public abstract class A {
    void method1(){
    method2();}
    abstract void  method2();
}

由于这仍然不容易如何翻译/实现java抽象类/多继承到go-lang这里是具有全面细节的帖子。 Abstract Class in golang