Go language Learning (15) object-oriented programming-interface

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

1. Interfaces for other languages

The interface of the go language is not the interface concept provided in other languages (C + +, Java, C #, etc.).
Prior to the advent of the Go language, the interface was primarily a contractual existence between different components. The implementation of the contract is mandatory, you
You must declare that you did implement the interface. In order to implement an interface, you need to inherit from the interface:

interface IFoo {    void// Java语法    // ...}

Even if there is an interface IFoo2 implements the same interface method as the IFoo, even the name is called IFoo only bit
Under different namespaces (package names), the compiler will also assume that the above class Foo implements only IFoo and does not implement the IFoo2 interface.
Such interfaces are called intrusive interfaces. The main manifestation of "intrusive" is that the implementation class needs to explicitly declare that it implements
An interface. This kind of mandatory interface inheritance is a very many questionable feature in the development of object-oriented programming.

2. Non-intrusive interface

In the go language, a class only needs to implement all the functions required by the interface, and we say that this class implements the interface,
For example:

typestruct {    // ...}func (f *File) Read(buf []byteint, err error)func (f *File) Write(buf []byteint, err error)funcint64intint64, err error)func (f *File) Close() error

Here we define a file class and implement methods such as read (), Write (), Seek (), Close (), and so on. Set
Think we have the following interface:

typeIFileInterface{Read (buf []byte) (nint, err Error) Write (buf []byte) (nint, err Error) Seek (offInt64, whenceint) (POSInt64, err Error) Close () Error}typeIreaderInterface{Read (buf []byte) (nint, err Error)}typeIwriterInterface{Write (buf []byte) (nint, err Error)}typeIcloserInterface{Close () error}

Although the file class does not inherit from these interfaces, it can even be unaware of the existence of these interfaces, as long as the file class
There are all the methods that contain these interfaces, which can be used as the following assignments.

varnew(File)varnew(File)varnew(File)varnew(File)

is not very strong, the biggest feature is not to explicitly (explicitly) declare that you implement an interface.

The non-intrusive interface of the go language seems to have made a small grammatical adjustment, but it has far-reaching implications.
First, the Go Language standard library, no longer need to draw the class Library inheritance tree diagram.

In go, the inheritance tree of the class is meaningless, you just need to know what the class implements, what each method means
Is enough.
Second, the implementation of the class, only need to care about what they should provide, no longer tangled interface needs to be more thin to
Reasonable. Interfaces are defined on demand by the consumer without prior planning.
Third, there is no need to import a package in order to implement an interface, because multiple references to an external package means more decoupling
Compliance The interface is defined by the consumer in terms of its own requirements, and the consumer does not have to care if other modules have defined similar interfaces.

3. Assignment of the interface

The interface assignment is divided into the following two scenarios in the Go language:
1) Assign the object instance to the interface;
2) Assign an interface to another interface.

First, we discuss assigning a certain type of object instance to the interface, which requires that the object instance implements all the methods required by the interface.
For example, before we did an Integer type, as follows:

typeintfuncbool {    return a < b}func (a *Integer) Add(b Integer) {    *a += b}

Accordingly, we define the interface Lessadder as follows:

typeinterface {    bool    Add(b Integer)}

Now there is a problem: Suppose we define an object instance of an integer type, how to assign it to Lessadder
What about the interface? Should I use the following statement (1) or a statement (2)?

var a Integer = 1var b LessAdder = &a ...(1)var(2)

The answer is that the statement (1) should be used. The reason is that the go language can be based on the following function:
func (a Integer) Less(b Integer) bool
Automatically generate a new less () method:

funcbool {    return (*a).Less(b)}

Thus, the type *integer has both the less () method and the Add () method, which satisfies all the methods of the Lessadder interface.

To further prove the reasoning above, we may as well define a lesser interface as follows:

typeinterface {    bool}

Then define an object instance of type integer and assign it to the lesser interface:

var a Integer = 1var b1 Lesser = &a ...//(1)var//(2)

As we expected, both the statement (1) and the statement (2) can be compiled and passed.

Let's discuss another scenario:
Assigns an interface to another interface. In the go language, only two interfaces
Having the same list of methods (which do not matter in order), then they are equivalent and can be assigned to each other.
For example:

package onetypeinterface {    Read(buf []byteint, err error)    Write(buf []byteint, err error)}

The second interface is in a different package:

package twotypeinterface {    Write(buf []byteint, err error)    Read(buf []byteint, err error)}

Here we have defined two interfaces, one called A. Readwriter, one called the other. Istream, both are defined
The read (), Write () method, just define the reverse order, one. Readwriter defines read () and then defines the
Write (), and both. IStream instead.
In the go language, these two interfaces are actually no different because:
1) any implementation of one. The class of the Readwriter interface is implemented in both. IStream;
2) any implementation of one. The class of the Readwriter interface is implemented in both. IStream;
3) Use one in any place. There is no difference between the Readwriter interface and the use of Two.istream.

The following code can be compiled by:

varnew(File)var file2 one.ReadWriter = file1var file3 two.IStream = file2

Interface assignment does not require two interfaces to be equivalent, if the method list of interface A is a subset of the method list of interface B,
Then interface B can assign a value to interface a. For example, suppose we have a writer interface:

typeinterface {    Write(buf []byteint, err error)}

You can put the one above. An instance of the Readwriter and Two.istream interfaces is assigned to the writer interface:

varnew(File)var file4 Writer = file1  //赋值给子集接口

But the reverse is not true:

varnew(File)var// 编译不能通过

This code cannot be compiled, because it is obvious: File1 does not have the read () method.

4. Interface Query

Is there a way to determine if the writer interface can be converted to a Two.istream interface?
Yes, that is the interface query syntax we are about to discuss, the code is as follows:

var file1 Writer = ...if file5, ok := file1.(two.IStream); ok {    ...}

This if statement checks whether the object instance pointed to by the File1 interface implements both. IStream interface, if implemented, the
Line-specific code.
Similar Java syntax instanceof, such as querying whether an object's type inherits from a type (base class query),
or whether an interface (interface derivation query) is implemented, but their dynamic query is very different from the dynamic query of Go.

5. Type Query

In the go language, you can also ask a more straightforward question about the type of object instances that the interface points to, such as:

varinterface{} = ...    switch v := v1.(type) {        caseint// 现在v的类型是int        casestring// 现在v的类型是string        ...}

Just as there are countless species in real life, the types in the language are countless, so type queries are not often
Use. It is more of a supplement that needs to be used in conjunction with interface queries, such as:

 PackageMainImport("FMT")typeStringerInterface{//define InterfacesString ()string}typeMystringerstruct{//define Structure body}func(*mystringer) String ()string{//methods of implementing Interfaces    return "This was a method implement from Stringer"}funcMain () {Println(123) Println ("Mchenys")varMystringer Stringer =New(Mystringer) Println (Mystringer)}funcPrintln (args ...Interface{}) {//variable parameters     for_, arg: =Rangeargs {SwitchV: = Arg. (type) {//Judgment type             Case int: FMT. Println ("Now"V"is of type int") Case string: FMT. Println ("Now"V"is of type string")default:ifV, OK: = arg. (Stringer); OK {//The type of V is now stringerVal: = v.string () fmt. Println (Val)}Else{FMT. Println ("Other types")                }        }    }}

Output Result:
Now the 123 type is int
Now the type of Mchenys is string
This was a method implement from Stringer

6. Combination of interfaces (nested)

Like the type (struct) combination described earlier, the Go language also supports interface combinations, such as:

// ReadWriter接口将基本的Read和Write接口组合起来typeinterface {    Reader    Writer}

This interface combines reader and writer two interfaces, which are exactly the same as the following:

typeinterface {    Read(p []byteint, err error)//Reader的方法    Write(p []byteint, err error)//Writer的方法}

Because the two ways of writing are identical: Readwriter interface can do all the things of reader interface, but also can do
Writer interface of all things. In the Go Language pack, there are a number of similar combinations of interfaces, such as Readwritecloser,
Readwriteseeker, Readseeker and Writecloser.

You can think of an interface combination as a specific scenario for an anonymous combination of types, except that the interface contains only methods and does not contain any
The member variable.

7.Any type

Because any object instance in the go language satisfies the null interface interface{}, interface{} looks like it can be
To point to any type of object, as follows:

var  v1 interface  {} = 1  //assign int type to interface{}  var  v2 interface  {} =  "abc"  //assign string type to interface{}  var  v3 interface  {} = &v2 //assign *interface{} type to interface{}  var  v4 interface  {} = struct  {X int }{1 }var  v5 interface  {} = & struct  {X int } {1 } 

When a function can accept arbitrary instances of an object, we declare it as interface{}, the most typical example being the standard
Functions of the Printxxx series in the quasi-Library FMT, for example:

funcstring, args ...interface{})func Println(args ...interface{})...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.