• 理解Go的多态实现


    总结两点:

    • 在Go中,定义一个interface类型,该类型说明了它有哪些方法。使用时,在函数中,将该interface类型作为函数的形参,任意一个实现了interface类型的实参都能作为该interface的实例对象。Go中没有implements关键字,与Java的实现多态相比,Go的组合更加灵活。
    • Go语言中没有继承,只有组合,可通过组合达到“继承”方法的目的。

    先看一个例子:

    /**
     * Animal 三个接口:fly(), swim() 和 run(),如果实现Animal,需要同时实现三个接口。
     */
    public interface Animal {
        public void fly();
        public void swim();
        public void run();
    }
    
    class Dog implements Animal {
        @Override
        public void fly() {
            System.out.println("Dog can not fly");
        }
    
        @Override
        public void swim() {
            System.out.println("Dog can not swim");
        }
    
        @Override
        public void run() {
            System.out.println("Dog can run");
        }
    }
    
    class Fish implements Animal {
        @Override
        public void fly() {
            System.out.println("Fish can not fly");
        }
    
        @Override
        public void swim() {
            System.out.println("Fish can swim");
        }
    
        @Override
        public void run() {
            System.out.println("Fish can not run");
        }
    }
    

    再来看Go的实现:

    type Animal1 interface {
    	fly()
    	swim()
    	run()
    }
    
    type Dog1 struct {
    }
    
    func (d Dog1) run() {
    	fmt.Println("dog can run")
    }
    
    type Fish struct {
    }
    
    func (f Fish) swim() {
    	fmt.Println("fish can swim")
    }
    

    可以看到,Go中实现需要的功能更灵活。这是多个实现类之间的比较,实现更加灵活。再看类似于“父子”之间的继承。

    import (
    	"fmt"
    	"reflect"
    )
    
    type Base struct {
    	// nothing
    }
    
    func (b *Base) ShowA() {
    	fmt.Println(reflect.TypeOf(b))
    	fmt.Println("showA")
    	b.ShowB()
    }
    func (b *Base) ShowB() {
    	fmt.Println(reflect.TypeOf(b))
    	fmt.Println("showB")
    }
    
    func (b *Base) ShowC() {
    	fmt.Println(reflect.TypeOf(b))
    	fmt.Println("showC")
    }
    //Derived 通过组合Base结构体,实现了伪继承,即拥有了ShowA和ShowB方法
    type Derived struct {
    	Base
    }
    //Derived 自己实现了ShowB方法,但不会自动做类型转换
    func (d *Derived) ShowB() {
    	fmt.Println(reflect.TypeOf(d))
    	fmt.Println("Derived showB")
    }
    
    type NewBase Base
    
    func main2() {
    	d := Derived{Base{}}
    	d.ShowA()  //Derived通过组合,有了ShowA()方法
    	/**
    	*main.Base
    	showA
    	*main.Base
    	showB
    	上述代码执行结果不会输出“Derived showB”,因为Go中没有继承的概念,只有组合.
    	上面的Derived包含了Base,自动的含有了Base的方法,因为其不是继承,所以不会根据具体传入的对象而执行对应的方法。
    	*/
    	d.ShowB()
    	/**
    	*main.Derived
    	Derived showB
    	*/
    
    	d.Base.ShowB()
    	/**
    	*main.Base
    	showB
    	d 通过组合获取了Base的方法 ShowB. 但如果d要调取Base的ShowB()方法(与d的ShowB()方法重复),需要显示调用Base.
    	*/
    	d.ShowC()
    	/**
    	*main.Base
    	showC
    	d 通过组合获取了Base的方法 ShowC.
    	 */
    	b := Base{}
    	b.ShowC()
    	//b1 := NewBase{}
    	//b1.ShowC()  //没有ShowC()方法
    	/**
    	上面的代码中b1不能执行ShowC()函数,因为Golang不支持隐式类型转换.
    	虽然newBase就是Base,但语法上它们是两种类型,因此newBase不能执行ShowC()方法。
    	 */
    }
    
  • 相关阅读:
    lamada基本语法
    idea 的全局搜索始终是上次的文本
    虚拟机中en33没有IP解决方法
    IDEA设置
    mysql主从配置
    linux安装mysql5.7(rpm方式)
    Jenkins+maven+github自动部署项目
    linux安装Jenkins
    linux wget安装jdk
    关于spring框架JdbcTemplate中的命令模式
  • 原文地址:https://www.cnblogs.com/shoren/p/golang-polymorphism.html
Copyright © 2020-2023  润新知