面向对象与面向过程:
举个例子:
加入要去吃烤鱼,
面向过程:自己动手,从买鱼,洗鱼洗菜,烤鱼,加调料等..
面向对象:来到烤鱼店,店菜单,吃,结账走人
所以总结如下:
面向过程:根据业务逻辑从上到下写代码
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
面向对象:对函数进行分类和封装,让开发速度更快
一. 创建类和对象
在python中,用变量去表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是"类",对象则是这一类事物中具体的一个
1.1 类的作用:属性引用和实例化
如以下代码:
class Person: # 定义一个类class couty = "china" # 类属性,静态属性 def __init__(self, *args): # # self 类似于一个字典 print(self.__dict__) # {} self.name=name # def walk(self): print("zou")
print(Person.couty) # 查看类的属性
print(Person.walk) # 查看类的方法
属性引用(类名.属性)
实例化:类名加括号,会触发_init_函数的运行,可以用它来为每个实例定制自己的特征
实例化的过程就是类----》对象的过程
语法:对象名=类名(参数)
egg = Person('xiaohei') #类名()就等于在执行Person.__init__() #执行完__init__()就会返回一个对象。这个对象类似一个字典,存着属于这个人本身的一些属性和方法。
查看属性&调用方法:
print(egg.name) # 查看属性 对象名.属性名
print(egg.walk()) # 调用方法:对象名.方法名()
关于self:在实例化时自动将对象/实例本身传给_init_的第一个参数,可以起和别的名字,但正常人都不会这么改的
1.2 对象:
class Person: # 定义一个人类 role = 'person' # 人的角色属性都是人 def __init__(self, name, aggressivity, life_value): self.name = name # 每一个角色都有自己的昵称; self.aggressivity = aggressivity # 每一个角色都有自己的攻击力; self.life_value = life_value # 每一个角色都有自己的生命值; def attack(self,dog): # 人可以发起攻击,这里被攻击的也是一个对象 dog.life_value -= self.aggressivity
对象是关于类而实际存在的一个例子,即实例
对象/实例只有一种作用:属性引用
xiaohei = Person('xiaohei',10,1000) # 根据类Person创建对象xiaohei print(xiaohei.name) print(xiaohei.aggressivity) print(xiaohei.life_value)
引用动态属性
print(egg.attack)
面向对象的固定模式
class 类名: def __init__(self,参数1,参数2): self.对象的属性1 = 参数1 self.对象的属性2 = 参数2 def 方法名(self):pass def 方法名2(self):pass 对象名 = 类名(1,2) #对象就是实例,代表一个具体的东西 #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法 #括号里传参数,参数不需要传self,其他与init中的形参一一对应 #结果返回一个对象 对象名.对象的属性1 #查看对象的属性,直接用 对象名.属性名 即可 对象名.方法名() #调用类中的方法,直接用 对象名.方法名() 即可
二. 面向对象三大特性
1.封装
封装,就是将内容封装到某个地方,以后再去调用被封装在某处的内容
# 创建类 class Boo: def __init__(self, name, age): # 构造方法,根据类创建对象时自动执行4 self.name = name self.age = age # 通过self间接调用被封装的内容 def datail(self): print(self.name) print(self.age) # 根据类Boo创建对象 # 自动执行Boo类的_init_方法 obj1 = Boo("xiaohei", 18) # 将xiaohei和18分别封装到obj的name和age属性中 # print(obj1.name) # 调用obj1对象的name属性 # print(obj1.age) # 调用obj1对象的age属性 obj1.datail() ## Python默认会将obj1传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18 obj2 = Boo("xiaoming", 20) # print(obj2.name) # print(obj2.age) obj2.datail()
2.继承
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容,将多个类共有的方法提取到父类中,子类仅需继承父类而不必实现每个方法
class Animal: def eat(self): print("%s 吃 " % self.name) def drink(self): print("%s 喝 " % self.name) def shit(self): print("%s 拉 " % self.name) def pee(self): print("%s 撒 " % self.name) class Cat(Animal): def __init__(self, name): self.name = name self.breed = '猫' def cry(self): print('喵喵叫') class Dog(Animal): def __init__(self, name): self.name = name self.breed = '狗' def cry(self): print('汪汪叫') # ######### 执行 ######### c1 = Cat('小白家的小黑猫') c1.eat() c2 = Cat('小黑的小白猫') c2.drink() d1 = Dog('胖子家的小瘦狗') d1.eat()
打印结果如下:
class 父类: def 父类中的方法(self): pass class 子类(父类): # 子类继承父类,即拥有了父类的所有方法 pass zilei = 子类() # 创建子类对象 zilei.父类中的方法() # 执行从父类中继承的方法
2.1多继承
python中类可以继承多个类,java和C#只能继承一个类
python的类如果继承多个类,寻找的方法有两种,分别是深度优先和广度优先
- 当类是经典类时,多继承情况下,会按照深度优先方式查找 A---->B---->D----->C
- 当类是新式类时,多继承情况下,会按照广度优先方式查找 A----->B---->C----->D
3.多态
多态的概念是用于Jave和C#语言上的,而python则崇尚"鸭子类型"
所谓多态:定义时的类型和运行时的类型不一样,此时就是多态
python伪代码实现Java或C#的多态
class F1(object): def show(self): print 'F1.show' class S1(F1): def show(self): print 'S1.show' class S2(F1): def show(self): print 'S2.show' # 由于在Java或C#中定义函数参数时,必须指定参数的类型 # 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类 # 而实际传入的参数是:S1对象和S2对象 def Func(F1 obj): """Func函数需要接收一个F1类型或者F1子类的类型""" print obj.show() s1_obj = S1() Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show s2_obj = S2() Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show
python的"鸭子类型"
鸭子类型:函数/方法可以接受一个任意类型的对象作为参数/返回值,只要该对象实现了代码后续用到的属性和方法就不会报错
代码如下:
class F1(object): def show(self): print 'F1.show' class S1(F1): def show(self): print 'S1.show' class S2(F1): def show(self): print 'S2.show' def Func(obj): print obj.show() s1_obj = S1() Func(s1_obj) s2_obj = S2() Func(s2_obj)