zoukankan      html  css  js  c++  java
  • Go 其六 重载,重写,覆盖 && DuckType 补充

    关于重载,重写,覆盖的基本概念要分清楚,
      Go中确实是不支持重载的, 官方给出的解释是
    其他语言的经验告诉我们,有各种同名但签名不同的方法有时是有用的,但在实践中也可能令人困惑。关于重载运算符,似乎更方便,但是同样的,没有重载会更简单。
    因此这么设计的目的其实 使Go语言保持简单 这一核心目标


      而关于重写和覆盖,emmm,笔者自己的理解是,毕竟不是真正的继承,而是复合。并且也不能像继承一样用父类定义而使用子类的实例充当具体实现,所以这个问题其实是不存在的?
    毕竟 var cat Pet = new(Cat) 是会报错的,没有继承又何谈重写或覆盖呢?

    关于这一部分的代码测试例子如下:

    package extension
    
    import (
    	"testing"
    	"fmt"
    )
    
    type Pet struct{
    }
    
    func (p *Pet) Speak() {
    	fmt.Print("In Pet ...")
    }
    
    // Go中不支持重载 以下代码会提示错误:
    /*
    	method redeclared: Pet.Speak
    	method(*Pet) func()
    	method(*Pet) func() stringgo
    */
    // func (p *Pet) Speak() string {
    // 	fmt.Print("In Pet ...")
    // 	return "Try to overload"
    // }
    
    func (p *Pet) SpeakTo(host string) {
    	p.Speak()
    	fmt.Println("In Pet ", host)
    }
    
    type Dog struct {
    	p *Pet
    }
    
    func (d *Dog) Speak() {
    	fmt.Print("In Dog ...")
    	d.p.Speak()
    }
    
    func (d *Dog) SpeakTo(host string) {
    	d.Speak()
    	fmt.Println("In Dog ", host)
    	d.p.SpeakTo(host)
    }
    
    type Cat struct{
    	Pet
    }
    
    func (c *Cat) Speak() {
    	fmt.Print("Try to overwrite Miao")
    }
    
    func TestDog(t *testing.T){
    	dog := new(Dog)
    	dog.SpeakTo("Hello")
    
    	//注意上面是复合不是集成
    
    	//注意还有Go中的匿名嵌套方法,感觉上像是继承
    	/*
    		type Cat struct {
    			Pet
    		}
    	*/
    
    	cat := new(Cat)
    	cat.SpeakTo("Miao")
    	//输出结果是In Pet ...In Pet  Miao(Pet中的方法)
    
    	//可以通过
    	var cat1 *Pet = new(Pet)
    	//下面一行会提示错误:cannot use new(Cat) (type *Cat) as type *Pet in assignmentgo
    	//var cat1 *Pet = new(Cat)
    	cat1.Speak()
    
    
    	//不同的写法也是一样的
    	//可以通过
    	var cat2 Pet = Pet{}
    	//提示错误:cannot use Cat literal (type Cat) as type Pet in assignment
    	//var cat2 Pet = Cat{}
    
    	cat2.Speak()
    }
    

       输出结果为:

    === RUN   TestDog
    In Dog ...In Pet ...In Dog  Hello
    In Pet ...In Pet  Hello
    In Pet ...In Pet  Miao
    In Pet ...In Pet ...--- PASS: TestDog (0.00s)
    === RUN   TestPolymorphism
    *extension.GoProgrammer, fmt.Println("Hello World!")
    extension.JavaProgrammer, System.out.Println("Hello World!")
    --- PASS: TestPolymorphism (0.00s)
    PASS
    coverage: [no statements]
    ok  	Session12/extension	0.276s	coverage: [no statements]
    

     

    关于DuckType还有一些补充内容:

    package extension
    
    import (
    	"testing"
    	"fmt"
    )
    
    type Code string
    type Programmer interface{
    	WriteHelloWorld() Code
    	//ReadHelloWorld() Code
    	//上面这个ReadHelloWorld() Code是一个实验
    	/*
    		如果一个接口没有实现接口的全部方法会怎样呢?
    			如果我们在接口里定义了ReadHelloWorld() Code这个方法,即使后面我们完全没有用到它
    			仍然会在build时提示错误:cannot use goProg (type *GoProgrammer) as type Programmer in argument to writeFirstProgram:
    				*GoProgrammer does not implement Programmer (missing ReadHelloWorld method)
    			
    		也就是说,虽然有Duck Type的存在,但如果一个结构没有实现接口的全部方法,那么这个结构就不能作为这个接口的实现。
    	*/
    }
    
    type GoProgrammer struct{
    }
    
    func (p *GoProgrammer) WriteHelloWorld() Code {
    	return "fmt.Println("Hello World!")"
    }
    
    type JavaProgrammer struct{
    }
    
    func (p JavaProgrammer) WriteHelloWorld() Code {
    	return "System.out.Println("Hello World!")"
    }
    
    func writeFirstProgram(p Programmer){
    	fmt.Printf("%T, %v
    ", p, p.WriteHelloWorld())
    }
    
    func TestPolymorphism(t *testing.T){
    	goProg := new(GoProgrammer)
    	javaProg := JavaProgrammer{}
    	writeFirstProgram(goProg)
    	writeFirstProgram(javaProg)
    
    	//Interface不只能传递指针类型,而是根据实例有没有实现interface的方法,例如上面的javaProg
    	//例如上面如果把 JavaProgram中的WriteHelloWorld方法定义更改为:func (p *JavaProgrammer) WriteHelloWorld() Code
    	//则会提示错误:cannot use javaProg (type JavaProgrammer) as type Programmer in argument to writeFirstProgram:
    	//JavaProgrammer does not implement Programmer (WriteHelloWorld method has pointer receiver)
    }
    

     

      总结一下就是,虽然有DuckType存在,不需要继承自接口, 但如果一个结构没有实现接口的全部方法,它仍然不能看作是这个接口的实现。

      另外Interface能不能传递指针类型,主要看实例实现接口时的方式。

  • 相关阅读:
    大数据的分页优化的思路
    escape()、encodeURI()、encodeURIComponent()区别详解
    PHP面向对象知识总结
    mysql 简单优化规则
    mysql语句内部优化
    js onmouseout的冒泡事件
    Android 开机自启动
    查看 AndroidManifest.xml文件
    Hierarchy Viewer显示视图性能指标
    Profile GPU rendering
  • 原文地址:https://www.cnblogs.com/dogtwo0214/p/13419080.html
Copyright © 2011-2022 走看看