首页 > 后端开发 > Golang > 正文

golang中有没有类

青灯夜游
发布: 2023-01-12 16:56:04
原创
3916 人浏览过

golang中没有类。golang不是一门纯面向对象编程语言,它没有class(类)的概念,也就没有继承的说法,但Go也可以模拟面向对象的编程方式。在Go中,可以将struct比作其它语言中的class;通过struct定义结构体,表征一类对象,例“type person struct {...}”。

golang中有没有类

本教程操作环境:windows7系统、GO 1.18版本、Dell G3电脑。

面向对象三大特征:封装,继承,多态。

Go不是一门纯面向对象编程语言,它没有class(类)的概念,也就没有继承的说法。但Go也可以模拟面向对象的编程方式,即可以将struct比作其它语言中的class。

对象

Go没有class的概念,通过struct定义结构体,表征一类对象。

type person struct {
	Age  int
	Name string
}
登录后复制

对象是状态与行为的有机体。例如下面的java代码:

public class Person {

    int age;

    String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
登录后复制

不同于Java,Go的方法不需要跟类的数据绑定在一个class的定义里面,只需要定义在同一个包内。这一点可能初学Go的同学,会感觉很奇怪。

type person struct {
	Age  int
	Name string
}

func (p *person) GetAge() int {
	return p.Age
}

func (p *person) SetAge(age int)  {
	p.Age = age
}

func (p *person) GetName() string {
	return p.Name
}

func (p *person) SetName(name string) {
	p.Name = name
}
登录后复制

构造函数

Go没有构造函数,对象的数据载体就是一个struct。Java支持构造函数,构造函数名字就跟类名字一样,多个构造函数通过函数重载实现。

而Go构造函数则通过工厂函数进行模拟。实例如下:

type person struct {
	Age  int
	Name string
}

/**
	构造函数1--通过名字初始化
 */
func newPersonByName(name string) *person {
	return &person{
		Name: name,
	}
}

/**
	构造函数2--通过年龄初始化
 */
func newPersonByAge(age int) *person {
	return &person{
		Age: age,
	}
}
登录后复制

需要注意的是,person结构体的名称首字母要小写,避免外部直接越过模拟的构造函数

访问权限

Java有四种访问权限,如下所示:

java访问控制符
  public protected
java访问控制符
  public protected

friendly

(default)

private
同一个类 yes yes yes yes
同一个包 yes yes yes no
不同包子类 yes yes no no
不同包非子类 yes no no no
friendly

(default)

private
同一个类 yes yes yes yes
同一个包 yes yes yes no
不同包子类 yes yes no no
不同包非子类 yes no no no
 

 

 

 

 

 

 

Go则做了简化,可见性的最小粒度是包。也就是说,Go保留两种,friendly和public。Go的变量名如果首字母是小写,则代表包内可见;如果首字母是大写,则代表任何地方都可见。

封装

封装,把抽象出来的结构体跟操作结构体内部数据的函数绑定在一起。外部程序只能根据导出的函数API(public方法)修改结构体的内部状态。

封装有两个好处:

隐藏实现:我们只希望使用者直接使用API操作结构体内部状态,而无需了解内部逻辑。就好像一座冰山,我们只看到它露出水面的那一部分。

保护数据:我们可以对数据的修改和访问施加安全措施,调用setter方法的时候,我们可以对参数进行校验;调用getter方法,我们可以增加访问日志等等。
type person struct {
	Age  int
	Name string
}

func NewPerson(age int, name string) *person{
	return &person{age, name}
}

func (p *person) SetAge(age int)  {
	p.Age = age
}

func (p *person) SetName(name string) {
	p.Name = name
}

func main() {
	p:= NewPerson(10, "Lily")
	p.SetName("Lucy")
	p.SetAge(18)
}
登录后复制

一个简单的bean定义如下所示:

func main() {
	p:= NewPerson(10, "Lily")

	p.SetName("Lily1")
	// 等价于下面的写法
	// p是一个引用,函数引用
	setNameFunc := (*person).SetName
	setNameFunc(p, "Lily2")
	fmt.Println(p.Name)
}
登录后复制

需要注意的是,Go的方法是一种特殊的函数,只是编译器的一种语法糖,编译器瞧瞧帮我们把对象的引用作为函数的第一个参数。例如,下面的代码是等价的

继承

继承,子类继承父类,则获得父类的特征和行为。继承的主要目的是为了重用代码。Java实现代码重用的两大利器,就是继承和组合。

Go没有class的概念,谈不上继承。但Go可以通过匿名组合来模拟继承。
type Animal struct {
	Name string
}

func (Animal) move()  {
	fmt.Println("我会走")
}

func (Animal) shout()  {
	fmt.Println("我会叫")
}

type Cat struct {
	Animal // 匿名聚合
}

func main() {
	cat := &Cat{Animal{"猫"}}

	cat.move()
	cat.shout()
}
登录后复制

如下所示,Cat通过匿名聚合了Animal结构体,就自动获得了Animal的move()和Shout()方法:

多态

多态,申明为基类的变量,可以在运行期指向不同的子类,并调用不同子类的方法。多态的目的是为了统一实现。
interface Animal {

    void move();

    void shout();
}

class Dog implements Animal {

    @Override
    public void move() {
        System.out.println("我会走");
    }

    @Override
    public void shout() {
        System.out.println("我会叫");
    }
}
登录后复制

我们通过接口来实现多态。在java里,我们通过interface来定义接口,通过implements来实现接口。

而Go则是通过
type Animal interface {

	move()
	shout()
}

type Cat struct {
	Animal // 匿名聚合
}

func (Cat)move()  {
	fmt.Println("猫会走")
}

func (Cat)shout()  {
	fmt.Println("猫会叫")
}

type Dog struct {
	Animal  // 匿名聚合
}


func (Dog)move()  {
	fmt.Println("狗会走")
}

func (Dog)shout()  {
	fmt.Println("狗会叫")
}

func main() {
	cat := Cat{}
	dog := Dog{}
    // 申明接口数组
 	animals := []Animal{cat, dog}
	for _,ele := range animals {
        // 统一访问
		ele.move()
		ele.shout()
	}
}
登录后复制
鸭子类型

推断,只要某个对象长得想鸭子,叫起来像鸭子,那么它就是鸭子。也就是说,Go的接口是比较隐匿的,只要某个对象实现来接口申明的所有方法,那么就认为它属于该接口。【相关推荐:Go视频教程

、编程教学】

以上是golang中有没有类的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板