有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

googlego中抽象类/方法(Java)的接口等价性

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

abstract class A{

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

 abstract method2();

}

class B extends A{

 method2(){
  ...
 }

}

class C extends A{

 method2(){
  ...
 }

}

我了解接口和结构。我可以构建一个接口,然后构建一个结构来实现method1。但是方法2呢? 我知道我可以将一个接口嵌入另一个接口,也可以将一个结构作为另一个结构的字段嵌入。但我看不到用这些方法实现我的结构的方法

我看到的唯一解决方案是在类B和类C中实现method1。难道没有其他方法吗

注意:当然,在我的例子中,这不仅仅是一种方法。另外,我有一个抽象类的层次结构,不想把所有的东西都下放到“子类”中

我在互联网上找到的例子大多是每个接口只有一个方法。如果你们中有人能给我一个提示,那就太好了!谢谢


共 (5) 个答案

  1. # 1 楼答案

    除非您从method1中删除static关键字,否则您正在询问的示例将不会在Java中编译,因此Java中正确的抽象类如下所示

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

    要在go lang中提供等效的接口,您必须以以下方式使用接口:Go Playground

    package main
    
    import (
        "fmt"
    )
    
    type AI interface {
        method2()
    }
    
    type A struct {
        AI
    }
    
    func (a * A) method1() {
       a.method2()
    }
    
    type B struct {
        *A
    }
    func (b *B) method2() {
       fmt.Print("Hello from B method1\n")
    }
    
    func NewB() *B{
       b := &B{}
       a := &A{b}
       b.A = a
       return b 
    }
    
    type C struct {
        *A
    }
    
    func (c *C) method2() {
        fmt.Print("Hello from C method1\n")
    }
    
    func NewC() *C{
        c := &C{}
        a := &A{c}
        c.A = a
        return c    
    }
    
    func main() {
    
         b := NewB()
         b.method1()
    
        c:= NewC()
        c.method1()
    }
    

    由于这仍然不容易,因此如何翻译/实现java抽象类/多重继承到go-lang,这里是一篇包含全面细节的文章Abstract Class in golang

  2. # 2 楼答案

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

    让我们假设我们的组件具有以下包结构

    component
      base
        types.go
        abstract.go
      impl1
        impl.go
      impl2
        impl.go
      types.go
      factory.go
    

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

    组件/类型。走

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

    现在让我们假设我们想要创建一个抽象类,它只实现SumAverage,但是在这个抽象实现中,我们希望能够使用已实现的AB返回的值

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

    组件/基础/类型。变强

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

    然后我们可以继续实现抽象的“类”

    组件/基础/抽象。走

    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
    }
    

    现在我们开始实现

    组件/impl1/impl。去//为执行2

    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包以使用抽象“类”,并且我们在components包中导入impl*包,以便工厂可以注册它们,我们将找到循环引用

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

    组件/工厂。走

    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. # 3 楼答案

    GO从面向对象的概念中获取闲聊,而不是像C++那样的模拟语言,而不是从C++获得它的面向对象概念的java。记住这一点,Go会突然变得清晰和明显

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

    Go类型不“实现”接口,它们只实现作为某些接口一部分的消息

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

    难怪我们在这里清楚地看到,在围棋中尝试实施ABC是一团混乱

  4. # 4 楼答案

    由于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
    
  5. # 5 楼答案

    您可以使用复合接口,例如来自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