本篇文章用于介绍python中的类与对象中的基础部分
先来做一个知识普及
在之前的教程中,我相信你已经学会了基础的编程方式,我将这种编程思维称之为(流水线式思维),而对于这种编程方式,叫做面向过程的程序设计。过程即是解决问题的步骤,面向过程的设计就好比精心设计好的一条流水线,在编写程序之前需要考虑周全什么时候处理什么事情,什么事情后处理。
这种编程方式既有优点又有缺点,优点就是:极大的降低了写程序的复杂度,只需要按照之前决定好的步骤逐步翻译即可。但是也有缺点:打个比方,一套流水线就是用来解决一个问题,代码一旦启动就会按照既定的流程逐步执行。
因为这个特性,面向过程编程常常用在一旦代码完成就很少更改的场景,比如说Linux内核
再来谈谈什么是对象
面向对象的程序设计的核心思想是“对象”(上帝式思维),可是到底什么是“对象”呢?举个例子:英雄联盟中的英雄们,每位英雄都有自己独特的特征和技能,在这里的英雄就可以理解为一个对象,特征和技能即对应对象的属性和方法,拿普通的5v5模式来讲,胜利的条件是摧毁敌方的水晶,这个水晶有它的血量,护甲,以及其他一系列的东西,这个水晶也可以看作一个对象。但是只有英雄和水晶两个对象未免有些无趣,所以又加入了其他很多很多元素,比如说敌方英雄,小兵,野怪等等各种对象。但是,当对象的数量多了起来的时候,面向过程的编程可能显得不那么适用,因为英雄间的对抗充满了随机性,所以我们引入面向对象编程,没有什么既定的流程,只要保证最后敌方的水晶爆炸即可。
由此可见,面向对象相对于面向过程来讲,更加的灵活,比如说我们要修改某一位英雄的属性,是增强或者削弱,这些都会反应在参数里。
但是面向对象也有着它的缺点,就是可控性差,我们没办法像面向过程一样精确预测问题的处理流程与结果,面向对象程序一旦开始就由对象之间互相交互解决问题。结果无法预测。
因此面向对象编程常常用在需求经常变化的软件里,比如说互联网应用,游戏等等。
现在来解释一下什么是类
类就是把一类事物的相同特征整合到一起就是类,类是一个抽象的概念。
打个比方——“人类”,我是人类,你也是人类,但是我有我自己的名字,你有你自己的名字。
这句话中可以看出,你我有一个共同的特点,都是人类,你我也有不同点,就是名字。从这个角度出发,“人”这一元素,就是一个类,相当于一个模板,而你和我,就是基于“人”这个类而创建的具体的事物,我们有着人类的一切特征,也有着我们独特拥有的属性,比如说“名字”。
类与对象
以上面的例子为例,这里我们新建一个类——human,并实例化一个对象——liuyaxing。
class Mankind: #创建Mankind类
def __init__(self, name, age): #初始化
self.name = name
self.age = age
def get_name(self): #为其设置类方法,用来打印名字
print("My name is {}".format(self.name))
def get_age(self): #为其设置另外一个类方法,用来打印年龄
print("My age is {}".format(self.age))
liuyaxing = Mankind('liuyaxing', 20) #类的实例化,从human这个类中产生liuyaxing这个对象
liuyaxing.get_name() #实现刘吖星所拥有的类方法
liuyaxing.get_age()
My name is liuyaxing
My age is 20
上面的一段代码给出了类和类的实例化最基本的写法,现在我们另外写一个类来逐一讲解。
如何定义一个类
首先,如果要是定义类的话,需要用到 class 语句,然后跟着类的名字,然后冒号。这样你的类就定义好了,就像这样:
class Human:
pass
注:一般类名都是首字母大写
为类赋予属性
现在人类(Human)这个种类有了,我们还需加上一些属性来描述这个种类,比如说每个人类都有名字name,每个人类也都拥有年龄age,所以 name 和 age 就是人类这个属性,为了简便这里只举例这两个属性,如果你有其他的想法也可以写下。
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
见到了 “def” 你可能会觉得很亲切,每当我们定义函数(方法)的时候,我们都会用到它,但是这个 def 是定义在一个类中的,所以在这里我们一般称它为 “类方法” ,当然你也可以称它为 “类函数” ,但你只需知道,类方法只能被这个类所实例化出的对象引用,而不能被其他类的对象引用即可。
打个比方,现在我们定义了一个植物类 plants 和刚刚我们定义的人类 Human ,因为植物和人类是不同的,我们人类有吃饭这个类方法,但是植物没有,所以植物不能引用吃饭这个方法。
类的初始化
明白了 def 的问题之后,我们接着向后看,“__init__” 在python中被称为初始化,有过 Java 基础的同学应该知道 _intit_ 在Java中被称之为构造方法。实际上构造方法和初始化应该是一个意思。
那么什么是构造方法/初始化呢?还是打个比方,在我们出生的时候,父母就为我们起好了名字,而从我们出生的那个时候起,即为一岁。实际上这个过程就被称为初始化。在我们实例化对象的时候,python 会自动调用 __init__ 方法,我们只需要传入参数即可完成对象的初始化。
注:__init__前后是两个下划线
什么是self,什么是 .
所谓的self,可以理解为“自己”,类似与C++ 或者 Java 中的 this 指针一样,就是对象自身的意思,当某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给 self, 所以开发者只需要传递后面的参数即可。
“.”可以理解为“属于”的意思,这在任何语言的任何语句中都适用。
所以,“self.name = name”这句话的意思就是:将 name 变量 赋值给 当前这个对象的 name属性,从而完成 name 这一属性的初始化
类方法
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
print("My name is {}".format(self.name))
def get_age(self):
print("My age is {}".format(self.age))
关于类方法是什么,之前已经说过了,但是我们之见到了init这一个类方法,这段代码中还有另外两个类方法,相信你能看出他们之间的区别,没错,后面的两个类方法前后没有下划线,其实没有下划线的方法是最普通的类方法,而带着下划线的init在python中被称为魔法方法,至于魔法方法是什么,之后会提到,你暂时可以先将他理解为,不一样的类方法。
在这段代码的后面,我又定义了两个普通的类方法,它们所能实现的功能很简单,就是分别打印对象的名字和年龄。
注:方法名的单词之间最好加上一个下划线,这样比较便于理解
类的实例化以及类方法的调用
好了现在我们已经将一个最简单的Human类定义完了,模板有了,让我们开使造小人吧(感觉好猥琐)。分析一下,类中有两个属性,分别是 name 和 age,当我们实例化对象的时候,需要传入这两个参数。
小强 = Human('小强',16)
这样我们就创建了一个人,他的名字叫小强,然后他拥有三个类方法,一个是初始化init,在我们创建小强时即被调是,另外两个是 getname() 和 getage(),现在我们可以调用这两个方法来查看小强的名字和年龄
小强.getname()
My name is 小强
小强.getage()
My age is 16
好了,关于面向对象的一些基础知识到这里就普及完了,后面的教程会继续展开对于面向对象的其他知识点。其实面向对象的编程方式很简单,却也很难,孰能生巧,你需要了解类和对象,要学会怎么定义类。望勤加练习
小测试
请编写一个程序,运用面向对象思维,实现三英战吕布。
小提示:定义一个英雄类,属性有血量,攻击力,防御力,等条件。