Go -- 扩展

Java的扩展

面向对象的扩展可以通过继承复合来实现,但Go并不支持继承

1
2
3
4
5
6
7
8
9
10
11
12
class Pet {
public void speak() {
System.out.println("Pet Speak");
}
}

class Dog extends Pet {
@Override
public void speak() {
System.out.println("Dog Speak");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class InheritTest {
@Test
public void subClassAccessTest() {
Pet dog = new Dog();
dog.speak(); // Dog Speak
}

@Test
// LSP : Liskov substitution principle
// 里氏替换原则:派生类(子类)对象可以在程式中代替其基类(超类)对象
public void lspTest() {
makePetSpeak(new Dog()); // Dog Speak
}

private void makePetSpeak(Pet pet) {
pet.speak();
}
}

Go的扩展

复合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
type Pet struct {
}

func (p *Pet) speak() {
fmt.Println("Pet Speak")
}

type Dog struct {
// 复合:通过Pet扩展Dog的功能
p *Pet
}

func (d *Dog) speak() {
d.p.speak()
fmt.Println("Dog Speak")
}

func TestComplex(t *testing.T) {
t.Logf("%T", Dog{}) // extension.Dog
t.Logf("%T", &Dog{}) // *extension.Dog
t.Logf("%T", new(Dog)) // *extension.Dog
dog := new(Dog)
dog.speak()
// 输出
// Pet Speak
// Dog Speak
}

匿名嵌套类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
type Pet struct {
}

func (p *Pet) speak() {
fmt.Println("Pet Speak")
}

func (p *Pet) eat() {
fmt.Println("Pet Eat")
}

type Dog struct {
// 匿名嵌套类型,不能当成继承使用
Pet
}

func (d *Dog) speak() {
fmt.Println("Dog Speak")
}

func TestAnonymousNestedType(t *testing.T) {
dog := new(Dog)
dog.eat() // Pet Eat
dog.speak() // Dog Speak
}

func TestNotInherit(t *testing.T) {
// 不符合LSP
// var d1 Pet = new(Dog) // cannot use new(Dog) (type *Dog) as type Pet in assignment
// var d2 Pet = Dog{} // cannot use Dog literal (type Dog) as type Pet in assignment
// var d3 Pet = (*Pet)(new(Dog)) // cannot convert new(Dog) (type *Dog) to type *Pet
}
0%