美文网首页
golang的父子类函数重载

golang的父子类函数重载

作者: CodingCode | 来源:发表于2020-02-23 09:34 被阅读0次

golang的父子类函数重载

首先声明一点golang没有传统面向对象语言的父子类关系,golang使用struct来定义数据类型,通过匿名成员的关系模拟父子类关系;所以这里说的父子类是便于对照c++/java语言的类型概念,便于讲述和理解。

  1. 定义

我们先定义父子类关系;
父类:A,定义了函数func Hello()
子类:B,简单继承了A
子类:C,简单继承了A,但重写了Hello()函数

代码如下:

type A struct {
   a int
}

func (n *A) Hello() {
    fmt.Println("in A::Hello")
}

type B struct {
   A
   b int
}

type C struct {
   A
   c int
}

func (n *C) Hello() {
    fmt.Println("in C::Hello")
}
  1. 验证重写功能
func main() {
    va := &A{}
    vb := &B{}
    vc := &C{}
    va.Hello()
    vb.Hello()
    vc.Hello()
}

运行:

in A::Hello
in A::Hello
in C::Hello

可见子类B并没有重写Hello函数,所以调用的实际上是A的函数;而类C重写了Hello。

  1. 子类里面如何调用父类的函数
func (n *C) Hello() {
    n.A.Hello()
    fmt.Println("in C::Hello")
}

func main() {
    vc := &C{}
    vc.Hello()
}

运行结果:

in A::Hello
in C::Hello

可见其语法是显示的指定父类的名。

  1. 虚函数

要说明虚函数,我们先定义一个Interface

type I interface {
    Hello()
}

这样前面的struct,A,B,和C都符合interface I的申明。

func foo(i I) {
  i.Hello()
}

func main() {
    va := &A{}
    vb := &B{}
    vc := &C{}
    foo(va)
    foo(vb)
    foo(vc)
}

运行结果:

in A::Hello
in A::Hello
in C::Hello

和我们预想的一样。

  1. 父类指针指向子类

在传统面向对象语言C++/Java里面我们经常会写类似函数,它使用一个父类指针作为参数,然后带使用的时候,可以传入父类的实例,或者子类的实例,然后在函数内用动态类型检测,比如dynamic_cast,来觉得传入的是父类还是子类。
还是以前面例子来说:C++版本:

#include <stdio.h>

class A {
public:
    virtual void Hello() { printf("in A::Hello\n"); }
};

class B : public A {
};

class C : public A {
public:
    virtual void Hello() { printf("in C::Hello\n"); }
};

void foo(A *p) {
    p->Hello();
}

int main(int argc, char * argv[]) {
    A * va = new A();
    B * vb = new B();
    C * vc = new C();
    foo(va);
    foo(vb);
    foo(vc);
}

编译运行:

in A::Hello
in A::Hello
in C::Hello

很好啊,然后golang是否有同样的功能呢?

func foo(v *A) {
  v.Hello()
}

func main() {
    va := &A{}
    vb := &B{}
    vc := &C{}
    foo(va)
    foo(vb)
    foo(vc)
}

编译:

# command-line-arguments
./main.go:43:8: cannot use vb (type *B) as type *A in argument to foo
./main.go:44:8: cannot use vc (type *C) as type *A in argument to foo

编译就出错了,golang根本就不认B/C和A是父子继承关系,golang认为A,B,和C是三种完全不同的数据类型,他们没有任何关系。

所以在golang里面是没有父类,子类这种概念关系的,所有的struct都是各自独立的,对于象:

type B struct {
   A
   b int
}

对于这种匿名成员关系,golang认为是内部的包含,而不是父子类关系。
那么golang如何实现抽象呢?答案就是用interface啊。

相关文章

  • golang的父子类函数重载

    golang的父子类函数重载 首先声明一点golang没有传统面向对象语言的父子类关系,golang使用struc...

  • C++派生类的友元函数,派生类的析构函数

    一、赋值兼容 运算符重载函数需要访问父类的私有成员,运算符重载函数是父类的友元函数,子类继承了父类,子类也可以使用...

  • 2020-07-07-《C++虚函数》

    虚函数可以让子类重写函数 子类重写父类中的虚函数 重写与重载的区别?

  • C++中重写、重载、重定义

    函数重载 必须在同一个类中进行 子类无法重载父类的函数 函数名字相同,参数不同,返回值可以不同 重载在编译期间根据...

  • C++ 重载 重定义 重写

    重载:在同一个类中,相同的函数名,不同的参数,称为函数重载,但是不能通过函数返回类型来判断。 重定义:在子类继承父...

  • 总结

    1,重载和重写的区别:重载:允许存在一个以上的同名函数,只要它们的参数类型不同即可。重写:当子类继承父类,沿袭了父...

  • 1.20、规则:当子类需要使用init函数时,确保已经重载了父类

    说明:当子类需要使用init函数时,确保已经重载了父类的构造函数 。否则,子类 的初始化不会调 用,这会导致很多很...

  • Java基础篇

    父类子类构造函数 子类的构造函数会隐式调用父类的无参构造函数,子类若想调用父类的构造函数需在子类的构造函数的第一行...

  • java-多态中方法重载和方法重写

    1.当子类重载父类的方法,父类不能引用该方法。只能引用自己的方法。2.当子类重写父类的方法,父类引用指向子类对象时...

  • java子类调用父类构造器函数

    子类 调用 父类的构造函数:(构造函数不会被继承,只是被子类调用而已) 1、子类所有的 构造函数 默认调用父类的无...

网友评论

      本文标题:golang的父子类函数重载

      本文链接:https://www.haomeiwen.com/subject/empdqhtx.html