大佬教程收集整理的这篇文章主要介绍了Is Go An Object Oriented Language?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
To truly understand what it means to be ‘object-oriented’ you need to look BACk at the origination of the concept. The first object oriented language,simula,emerged in the 1960s. It introduced objects,classes,inheritance and subclasses,virtual methods,coroutInes,and a lot more. Perhaps most importantly,it introduced a paradigm shift of thinking of data and logic as completely independent.
While you many not be familiar with Simula,you are no doubt familiar with languages that refer to it as their inspiration including Java,C++,C# & smalltalk,which in turn have been the inspiration for Objective C,Python,Ruby,Javascript,Scala,PHP,Perl… a veritable list of nearly all popular languages in use today. This shift in thinking has taken over,so much so that most progrAMMers alive today have never written code any other way.
Since a standard deFinition doesn’t exist,for the purpose of our discussion we will provide one.
Rather than structure programs as code and data,an object-oriented system integrates the two using the concept of an “object”. An object is an abstract data type that has state (data) and behavior (codE).
Perhaps as a consequence of the initial implementation having inheritance and polymorphism,a feature virtually all of the derivatives also adopted,deFinitions of object oriented progrAMMing typically also include those features as requirements.
We will look at how Go does objects,polymorphism and inheritance and allow you to make your own conclusion.
Go doesn’t have a something called ‘object’,but ‘object’ is only a word that connotes a meaning. It’s the meaning that matters,not the term itself.
While Go doesn’t have a type called ‘object’ it does have a type that matches the same deFinition of a data structure that integrates both code and behavior. In Go this is called a ‘struct’.
A ‘struct’ is a kind of type which contains named fields and methods.
Let’s use an example to illustrate this:
type rect struct { width int height int } func (r *rect) area() int { return r.width * r.height } func main() { r := rect{width: 10,height: 5} fmt.Println("area: ",r.area()) }
There’s a lot we Could talk about here. It’s probably best to walk through the code line by line and explain what is happening.
The first block is defining a new type called a ‘rect’. This is a struct type. The struct has two fields,both of which are type int.
The next block is defining a method bound to this struct. This is accomplished by defining a function and attaching (binding) it to a rect. Technically,in our example it is really attached to a pointer to a rect. While the method is bound to the type,Go requires us to have a value of that type to make the call,even if the value is the zero value for that type (in the case of a struct the zero value is nil).
The final block is our main function. The first line creates a value of type rect. There are other Syntaxes we Could use to do this,but this is the most i@L_793_8@matic way. The second line prints to the output the result of calling the area function on our rect ‘r’.
To me this feels very much like an object. I am able to create a structured data type and then define methods that interact with that specific data.
what haven’t we done? In most object oriented languages we would be using the ‘class’ keyword to define our objects. When using inheritance it is a good practice to defin@R_489_9473@erfaces for those classes. In doing so we would be defining an inheritance hierarchy tree (in the case of single inheritancE).
An additional thing worth noting is that in Go any named type can have methods,not only structs. For example I can define a new type ‘Counter’ which is of type int and define methods on it. See an example athttp://play.golang.org/p/LGB-2j707c
The Gang of Four Design Patterns book discusses at length replacing implementation inheritance (extends) with interface inheritance (implements).
I once attended a Java user group meeTing where James Gosling (Java’s inventor) was the featured speaker. During the memorable Q&A session,someone asked him: “If you Could do Java over again,what would you change?” “I’d leave out classes,” he replied. After the laughter died down,he explained that the real problem wasn’t classes per se,but rather implementation inheritance (the extends relationship). Interface inheritance (the implements relationship) is preferable. You should avoid implementation inheritance whenever possible.
An good example of this would be the relationship between a Person and an Address.
type Person struct { Name String Address Address } type Address struct { number String Street String City String State String Zip String } func (p *Person) Talk() { fmt.Println("Hi,my name is",p.Name) } func (p *Person) LOCATIOn() { fmt.Println("I’m at",p.Address.number,p.Address.Street,p.Address.City,p.Address.State,p.Address.Zip) } func main() { p := Person{ Name: "Steve",Address: Address{ number: "13",Street: "Main",City: "Gotham",State: "NY",Zip: "01313",},} p.Talk() p.LOCATIOn() }
> Hi,my name is Steve > I’m at 13 Main Gotham NY 01313
http://play.golang.org/p/LigPIVT2mf
Important things to realize from this example is that Address remains a disTinct entity,while exisTing within the Person. In the main function we demonstrate that you can set the p.Address field to an address,or simply set the fields by accessing them via dot notation.
The pseudo is-a relationship works in a similar and intuitive way. To extend our example above. Let’s use the following statement. A Person can talk. A Citizen is a Person therefore a citizen can Talk.
This code depends on and adds to the code in the example above.
type Citizen struct { Country String Person } func (c *Citizen) Nationality() { fmt.Println(c.Name,"is a citizen of",c.Country) } func main() { c := Citizen{} c.Name = "Steve" c.Country = "America" c.Talk() c.Nationality() }
http://play.golang.org/p/eCEpLkQPR3
We accomplish this pseudo is-a relationship in go using what is called an Anonymous field. In our example Person is an anonymous field of Citizen. Only the type is given,not the field name. It assumes all of the properties and methods of a Person and is free to use them or promote it’s own.
An example of this would be that citizens Talk just as People do,but in a different way.
For this we simply define Talk for *Citizen,and run the same main function as defined above. Now instead of calling *Person.Talk(),*Citizen.Talk() will be called instead.
func (c *Citizen) Talk() { fmt.Println("Hello,c.Name,"and I'm from",c.Country) }
http://play.golang.org/p/jafbVPv5H9
This isn’t necessarily a bad thing. One of the issues with multiple inheritance is that languages are often non obvIoUs and sometimes even ambiguous as to which methods are used when identical methods exist on more than one parent class.
With Go you can always access the individual methods through a property which has the same name as the type.
In reality when you are using Anonymous fields,Go is creaTing an accessor with the same name as your type.
In our example from above the following code would work:
func main() { c := Citizen{} c.Name = "Steve" c.Country = "America" c.Talk() // <- Notice both are accessible c.Person.Talk() // <- Notice both are accessible c.Nationality() }
:1em; unicode-bidi:embed; white-space:pre-wrap; border:0px; word-wrap:break-word; line-height:1.4; font-size:21px; BACkground-color:rgb(248,my name is Steve and I'm from America > Hi,my name is Steve > Steve is a citizen of America
If this was truly subtyping then the anonymous field would cause the outer type to become the inner type. In Go this is simply not the case. The two types remain disTinct. The following example illustrates this:
package main type A struct{ } type B struct { A //B is-a A } func save(A) { //do something } func main() { b := B save(&b); //OOOPS! b IS NOT A }
> prog.go:17: cAnnot use b (type *B) as type A in function argument > [process exited with non-zero status]
http://play.golang.org/p/dt1mTXW-BH
The prevIoUs example came directly from aresponse to this poston Hacker News. Thanks Optymizer!
As we wrote above,subtyping is the is-a relationship. In Go each type is disTinct and nothing can act as another type,but both can adhere to the sam@R_489_9473@erface. Interfaces can be used as input and output of functions (and methods) and consequently establish an is-a relationship between types.
Adherence to an interface in Go is defined not through a keyword like ‘using’ but through the actual methods declared on a type. InEfficient Goit refers to this relationship as ‘if something can do this,then it can be used here.’ This is very important because it enables one to create an interface that types defined in external packages can adhere to.
ConTinuing with the example from above,we add a new function,SpeakTo and modify the main function to try to SpeakTo a Citizen and a Person.
func SpeakTo(p *Person) { p.Talk() } func main() { p := Person{name: "Dave"} c := Citizen{Person: Person{name: "Steve"},Country: "America"} SpeakTo(&p) SpeakTo(&C) }
http://play.golang.org/p/lvEjaMQ25D
As expected,this fails. In our code a Citizen isn’t a Person,even though they share many of the same properties,they are viewed as disTinct types.
However if we add an interface called Human and use that as the input for our SpeakTo function it will all work as intended.
type Human interface { Talk() } func SpeakTo(h Human) { h.Talk() } func main() { p := Person{name: "Dave"} c := Citizen{Person: Person{name: "Steve"},Country: "America"} SpeakTo(&p) SpeakTo(&C) }
http://play.golang.org/p/ifcP2mAOnf
There are two critical points to make about subtyping in Go:
We can use Anonymous fields to adhere to an interface. We can also adhere to many interfaces. By using Anonymous fields along with interfaces we are very close to true subtyping.
@H_255_197@Go does provide proper subtyping capabilities,but only in the using of a type. Interfaces can be used to ensure that a variety of different types can all be accepted as input into a function,or even as a return value from a function,but in reality they retain their disTinct types. This is clearly displayed in the main function where we cAnnot set Name on Citizen directly because Name isn’t actually a property of Citizen,it’s a property of Person and consequently not yet present during the initialization of a Citizen.
Go utilizes structs as the union of data and logic. Through composition,has-a relationships can be established between Structs to minimize code repetition while staying clear of the brittle mess that is inheritance. Go uses interfaces to establish is-a relationships between types without unnecessary and counteractive declarations.
Welcome to the new ‘object’-less OO progrAMMing model.
以上是大佬教程为你收集整理的Is Go An Object Oriented Language?全部内容,希望文章能够帮你解决Is Go An Object Oriented Language?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。