未来编程形式设想

对于未来的编程形式,会不会像太极(tai-chi)一样充分发挥自己的设立能力和想象能力呢?

YouTube – Iron Man 2 – SFX montage by Prologue Films.

It’s too far away to think about this. ^_^哈哈!


weixing publiv account

下面的文章就是对Go语言的基本介绍。

We will look at how Go does objects, polymorphism and inheritance and allow you to make your own conclusion.

Objects In Go
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 idiomatic 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 define interfaces 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 at http://play.golang.org/p/LGB-2j707c

Inheritance And Polymorphism
There are a few different approaches to defining the relationships between objects. While they differ quite a bit from each other, all share a common purpose as a mechanism for code reuse.

Inheritance
Multiple Inheritance
Subtyping
Object composition
Single & Multiple Inheritance
Inheritance is when an object is based on another object, using the same implementation. Two different implementations of inheritance exist. The fundamental distinction between them is whether an object can inherit from a single object or from multiple objects. This is a seemingly small distinction, but with large implications. The hierarchy in single inheritance is a tree, while in multiple inheritance it is a lattice. Single inheritance languages include PHP, C#, Java and Ruby. Multiple inheritance languages include Perl, Python and C++.

Subtyping (Polymorphism)
In some languages subtyping and inheritance are so interwoven that this may seem redundant to the previous section if your particular perspective comes from a language where they are tightly coupled. Subtyping establishes an is-a relationship, while inheritance only reuses implementation. Subtyping defines a semantic relationship between two (or more) objects. Inheritance only defines a syntactic relationship.

Object Composition
Object composition is where one object is defined by including other objects. Rather than inheriting from them, the object contains them. Unlike the is-a relationship of subtyping, object composition defines a has-a relationship.

Inheritance In Go
Go is intentionally designed without any inheritance at all. This does not mean that objects (struct values) do not have relationships, instead the Go authors have chosen to use a alternative mechanism to connote relationships. To many encountering Go for the first time this decision may appear as if it cripples Go. In reality it is one of the nicest properties of Go and it resolves decade old issues and arguments around inheritance.

Inheritance Is Best Left Out
The following really drives home this point. It comes from a JavaWorld article titled why extends is evil :

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.

Polymorphism & Composition In Go
Instead of inheritance Go strictly follows the composition over inheritance principle. Go accomplishes this through both subtyping (is-a) and object composition (has-a) relationships between structs and interfaces.

Object Composition In Go
The mechanism Go uses to implement the principle of object composition is called embedded types. Go permits you to embed a struct within a struct giving them a has-a relationship.

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()
}

Output

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.

Pseudo Subtyping In Go
AUTHORS NOTE:
In the first version of this post it made the incorrect claim that Go supports the is-a relationship via Anonymous fields. In reality Anonymous fields appear to be an is-a relationship by exposing embedded methods and properties as if they existed on the outer struct. This falls short of being an is-a relationship for reasons now provided below. Go does have support for is-a relationships via interfaces, covered below. The current version of this post refers to Anonymous fields as a pseudo is-a relationship because it looks and behaves in some ways like subtyping, but isn’t.

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()
}

Output

Hi, my name is Steve
Steve is a citizen of America
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.

Promoting Methods Of Anonymous Fields

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, my name is", c.Name, "and I'm from", c.Country)
}

Output

Hello, my name is Steve and I’m from America
Steve is a citizen of America

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值