golang是面向对象吗
Sometimes I read an article that says “Go is object oriented”. Sometimes another article that claims that no object oriented programming can be done with Go, just because it does not have classes.
有时我读到一篇文章,说“ Go是面向对象的”。 有时,另一篇文章声称Go不能完成面向对象的编程,只是因为它没有类。
So I wrote this post to clarify this topic. Is Go object oriented, or not?
所以我写了这篇文章来澄清这个话题。 Go是否面向对象?
If you’re used to think in a particular language, depending on which language you’re coming from, you might have a different take on this topic. For example if you come from C, clearly Go has lots more object oriented programming features. Coming from Java, Go code doesn’t look much object oriented.
如果您习惯用一种特定的语言思考,这取决于您使用的是哪种语言,那么您可能对这个主题有不同的看法。 例如,如果您来自C,那么显然Go具有更多的面向对象编程功能。 来自Java,Go代码看起来不太面向对象。
What you need to do in this case is stop thinking in terms of the “other language”, and think with a Go mindset first.
在这种情况下,您需要做的就是停止以“其他语言”的方式思考,而首先以Go的思维方式进行思考。
Here’s my answer: Yes, Go is object oriented, and in a refreshing a sane way.
这是我的答案: 是的 ,Go是面向对象的,并且是一种全新的理智方式。
The Go FAQ says:
常见问题解答说:
Go是一种面向对象的语言吗? (Is Go an object-oriented language?)
Yes and no. Although Go has types and methods and allows an object-oriented style of programming, there is no type hierarchy. The concept of “interface” in Go provides a different approach that we believe is easy to use and in some ways more general. There are also ways to embed types in other types to provide something analogous—but not identical—to subclassing. Moreover, methods in Go are more general than in C++ or Java: they can be defined for any sort of data, even built-in types such as plain, “unboxed” integers. They are not restricted to structs (classes).
是的,没有。 尽管Go具有类型和方法,并允许使用面向对象的编程风格,但没有类型层次结构。 Go中的“界面”概念提供了一种不同的方法,我们认为该方法易于使用,并且在某些方面更通用。 还有一些方法可以将类型嵌入其他类型,以提供与子类类似(但不完全相同)的东西。 而且,Go中的方法比C ++或Java中的方法更通用:可以为任何类型的数据定义它们,甚至可以将内置类型(例如普通的“未装箱”整数)定义为它们。 它们不限于结构(类)。
Also, the lack of a type hierarchy makes “objects” in Go feel much more lightweight than in languages such as C++ or Java.
而且,缺乏类型层次结构使得Go中的“对象”比C ++或Java等语言更轻量。
樱桃采摘概念 (Cherry-picking concepts)
Go picked some concepts from procedural programming, functional programming and object oriented programming, and put them together, and left out other concepts to create its own unique flavour of idiomatic programming style.
Go从过程式编程,函数式编程和面向对象的编程中选择了一些概念,并将它们组合在一起,并省略了其他概念以创建自己独特的惯用编程风格。
没有课程,请输入结构 (No classes, enter structs)
There are no classes in Go, in their traditional concept, but Go has struct types, which are much more powerful than their C counterpart. Struct types plus their associated methods serve the same goal of a traditional class, where the struct only holds the state, not the behavior, and the methods provide them behavior, by allowing to change the state.
按照传统概念,Go中没有类,但是Go具有结构类型,其结构比C语言更强大。 结构类型及其关联方法达到了传统类的相同目标,在传统类中,结构仅保存状态,不保存行为,并且这些方法通过允许更改状态来提供行为。
封装形式 (Encapsulation)
One of the best features of Go: capitalized fields, methods and functions are public. All the other fields are local to the package and not exported. With a single look you know if something is public or private. There’s no protected because there is no inheritance.
Go的最佳功能之一:大写的字段,方法和功能是公开的。 所有其他字段对于包来说是本地的,不导出。 一眼就能知道是公共的还是私人的。 没有保护,因为没有继承。
没有继承 (No inheritance)
There is no concept of inheritance. From the Go FAQ:
没有继承的概念。 从Go常见问题解答:
Object-oriented programming, at least in the best-known languages, involves too much discussion of the relationships between types, relationships that often could be derived automatically. Go takes a different approach.
至少以最著名的语言进行的面向对象编程涉及对类型之间的关系的过多讨论,而这些关系通常可以自动派生。 Go采用了不同的方法。
组成重于继承 (Composition over inheritance)
This well known principle, also mentioned in the Gang of Four book, is found a lot in Go code.
在Go代码中也发现了这一众所周知的原理 ,在《四人帮》一书中也有提到。
When declaring a struct we can add an unnamed (anonymous) field, which causes its fields and its methods to be exposed on the struct. This is called struct embedding:
声明结构时,我们可以添加一个未命名(匿名)字段,这将导致其字段及其方法在结构上公开。 这称为结构嵌入 :
package main
import (
"fmt"
)
type Dog struct {
Animal
}
type Animal struct {
Age int
}
func (a *Animal) Move() {
fmt.Println("Animal moved")
}
func (a *Animal) SayAge() {
fmt.Printf("Animal age: %d\n", a.Age)
}
func main() {
d := Dog{}
d.Age = 3
d.Move()
d.SayAge()
}
介面 (Interfaces)
Forget Java and PHP-style interfaces. Go interfaces are very different, and one key concept is that interfaces are satisfied implicitly.
忘记Java和PHP风格的接口。 Go接口有很大的不同,一个关键概念是隐式满足接口。
From the Go FAQ:
从Go常见问题解答:
Rather than requiring the programmer to declare ahead of time that two types are related, in Go a type automatically satisfies any interface that specifies a subset of its methods.
在Go中,类型无需自动声明两种类型相关联,而可以自动满足指定其方法子集的任何接口。
Interfaces are typically very small, up to being just one method. You won’t see long lists of methods in idiomatic Go.
接口通常很小,最多只是一种方法。 您不会在惯用的Go中看到很长的方法列表。
Interfaces elegantly provide polymorphism: by accepting an interface, you declare to accept any kind of object satisfying that interface.
接口优雅地提供了多态性 :通过接受接口,您可以声明接受任何满足该接口的对象。
方法 (Methods)
Types have methods. They are defined outside the type definition, with a syntax that might recall the JavaScript prototype method definitions:
类型有方法。 它们是在类型定义之外定义的,其语法可能会调用JavaScript原型方法定义:
function Person(first, last) {
this.firstName = first;
this.lastName = last;
}
Person.prototype.name = function() {
return this.firstName + " " + this.lastName;
};
p = new Person("Flavio", "Copes")
p.name() // Flavio Copes
in Go the same code is written as:
在Go中,相同的代码编写为:
package main
import (
"fmt"
)
type Person struct {
firstName string
lastName string
}
func (p Person) name() string {
return p.firstName + " " + p.lastName
}
func main() {
p := Person{"Flavio", "Copes"}
fmt.Println(p.name())
}
将方法附加到类型 (Attach methods to types)
Methods can be attached to any type, even basic data types. Since methods can only be attached in the same package where the type is defined, we cannot “enrich” the built-in basic types, but we can enrich any named type we create with a base type underlying representation:
方法可以附加到任何类型,甚至是基本数据类型。 由于方法只能附加在定义类型的同一包中,因此我们不能“丰富”内置的基本类型,但是可以使用基础类型作为基础表示形式来丰富我们创建的任何命名类型:
package main
import (
"fmt"
)
type Amount int
func (a *Amount) Add(add Amount) {
*a += add
}
func main() {
var a Amount
a = 1
a.Add(2)
fmt.Println(a)
}
功能 (Functions)
Think about a traditional object oriented programming language like Java. How many times did you define a “Utils” class with static methods?
考虑一下像Java这样的传统的面向对象的编程语言。 您用静态方法定义了几次“ Utils”类?
This is to workaround the notion that everything is an object, and function definitions must be inside classes. Such thing does not happen with Go, because Go has functions. Not everything needs to be an object, or a method, in the real world. “Classes” and “objects” are very useful but they cannot be used for everything.
这是为了解决所有事物都是对象,并且函数定义必须在类内部的观念。 Go不会发生这种事情,因为Go具有功能。 在现实世界中,并非所有事物都需要成为对象或方法。 “类”和“对象”非常有用,但不能用于所有事物。
In Go not everything is an object (and technically nothing is an object, but some people call type values and variables “objects”), methods are functions associated to a type, but Go also allows functions to live outside an object, just like C functions.
在Go中,并非所有事物都是对象(从技术上讲,不是所有东西都是对象,但是有些人称类型值和变量为“对象”),方法是与类型关联的函数,但是Go也允许函数驻留在对象外部,就像C功能。
So, although Go allows methods, it also allows functions, and first class functions (functions can be stored as struct fields, can be passed as arguments to other functions, can be returned from a function or methods return value).
因此,尽管Go允许使用方法,但它也允许使用函数和一等函数 (函数可以存储为struct字段,可以作为参数传递给其他函数,可以从函数或方法的返回值中返回)。
少膨胀 (Less bloat)
Overall the Go implementation of object oriented programming is incredibly flexible and direct. Leaving behind classes and inheritance, you’ll see very little boilerplate, and instead of reasoning about the perfect hierarchical structure for classes, which becomes hard to change, you have the freedom to compose and decompose types as needed.
总的来说,面向对象编程的Go实现非常灵活和直接 。 抛开类和继承,您将看到很少的样板,并且无需推理类的完美分层结构(难于更改),而是可以根据需要自由地组合和分解类型。
golang是面向对象吗