带有class关键字语言中的面向对象
先看看常见的面向对象语言中是怎么处理的
- 抽象
- 封装
- 继承
- 多态
这四个是面向对象的四个基本特征
- 抽象, 就是将某一类事务的特征进行提取的过程
- 封装, 将抽象出来的东西, 用一个类进行存储
- 继承, 类与类之间可以实现继承关系, 子类将获得父类公有的属性和方法
- 多态, 一个类的中的某个成员函数, 可以对不同的参数执行不同的行为
比如下面这个例子, 就是对属性和行为的封装, age 属于属性, run 属于行为
class human{
public int age;
public void run(){
}
}
下面这个则是实现了继承(实现的前提是这两个类在现实生活中有可提供依据的从属关系), man 具有 human 中的所有特征,所以, 可以实现继承关系, man 也自然获得了 human 中的 age 属性和 run 这个行为
class man extends human{
public void stronger(){
}
}
多态则可这样实现, 标准步骤为:
- 接口中写入抽象方法
- 父类实现接口并实现抽象法法
- 子类继承父类
- 重写父类中的抽象方法
然后根据输入参数的不同, 在函数内实现相应的功能即可, 在这里重写的是 run , 因为可以根据年龄段的不同, 决定这个人跑的速度有多快, 所以, 这个也是符合现实中的规则的
class man extends human{
public void stronger(){
}
@Override
public void run(int ages){
}
}
如果没有 class 关键字了, 该怎么办?
实际上,没有 class 关键字也能实现上述 Java 中面向对象的一系列形式, 一开始可能觉得不可思议, 但是理解之后肯定会和李云龙一样惊叹一句:你TND还真是个天才
go语言中就没有这个 class 关键字, 也没有类这个概念
但是在 go 语言中, 提供了类似 C 语言结构体一样的东西, 而且, go 语言中函数的定义也是有点奇特
这是 go 语言中结构体的定义
结构体是用于存储多个变量的, 把他们组合在一起, 那么, 类中的变量(属性)是不是可以用结构体存储呢?
而且, 一个结构体都有独一无二的名字, 是不是就能代表类名了呢?
这是 go 语言中普通函数的定义
再来看看函数, 普通函数和其他语言差距不大, 但是成员函数(方法)却不一样了
这是 go 语言中成员函数(方法)的定义
与普通函数不一样的是, 函数名前面多了一个参数, 而且是唯一的, 是一个叫做接收者的参数, 这个说白了, 就相当于前面提到的结构体的一个引用, 这不就可以用来辨别这个函数是属于哪个结构体(类)了
继承又该怎么实现呢?
结构体嵌套就完事了
这是 go 语言中接口的定义
接口用法就和 Java 中的差不多了, 里面都是抽象函数, 通常用于实现多态
但是 golang 中有个习惯上的约定, 一个接口在绝大多数情况下, 只有一个抽象方法, 这个和 Java 不一样
面向对象只是一个思想, 并不和 class 关键字绑定
面向对象是一种编程思想, 并不和 class 这种关键字画等号, go 语言中没有class 关键字都可以实现面向对象的这些东西, 所以, 只凭借有没有 class 关键字就判定一门语言是不是面向对象的语言, 相反, C 语言也能实现上面这些, C++ 在刚出来的时候, 都是先翻译成 C 语言代码, 然后进行编译的, 可是 C 语言却是面向过程的语言。 在理解 go 语言这个设计技巧之后, 对于 C++ 翻译成 C 语言再进行编译的过程我也理解更多了, 其实他们两个处理面向对象这些元素的方法很相似。