Python-面向对象编程

时间:2022-04-23
本文章向大家介绍Python-面向对象编程,主要内容包括概述:、创建类和对象、面向对象的三大特性、二:继承、三:多态、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

概述:

  • 面向过程:根据业务逻辑从上到下写代码。
  • 函数式:将某功能代码封装到函数中,以后便无需重复编写,进调用函数即可。
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强”

创建类和对象

面向对象编程需要类和对象来实现,其实就是对类和对象的使用。

类是什么?

类就是一个模版,模版里包含多个函数,函数里实现一些功能。

对象是什么?

对象则是根据模版创建的实例,通过实例对象可以执行类中的函数

  • class是关键字,表示类
  • 创建对象,类名称后加括号就是创建对象
  • 类中的函数第一个参数必须是self(是函数三大特性之一封装性)
  • 类中定义的函数叫方法

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

#!/usr/bin/env python # coding:utf-8 # 创建类 class Foo:     # 创建类中的函数     def Bar(self):         print "Bar"     def Hello(self,name):         print 'I am %s' %name # 根据类Foo创建obj obj = Foo() # 执行Bar方法 obj.Bar() # 执行Hello方法 obj.Hello('caoxiaojian')

  • 面向对象:【创建对象】==【通过对象执行方法】
  • 函数编程:【执行函数】

函数是式的应用场景:各个函数之间是独立的且无共用的数据。

面向对象的三大特性

三大特性是:封装性、继承性、多态性。

一:封装

含义:就是将内容封装到某个地方,以后再去调用倍封装在某处的内容

使用方式:

  1. 将内容封装到某处
  2. 从某处调用被封装的内容

A:将内容封装到某处

#!/usr/bin/env python
# coding:utf-8
# 创建类
class Foo:
    def __init__(self,name,age):  #称为构造方法,根据类创建对象时自动执行
        self.name = name
        self.age = age
# 根据类Foo创建对象obj1
# 自动执行Foo类的 __init__方法
obj1 = Foo('caoxiaojian','24')  # 将caoxiaojian和24分别封装到obj1(self)的name和age属性中

# 根据类Foo创建对象obj2
# 自动执行Foo类的 __init__方法
obj2 = Foo('caogaotian','23')   # 将caogoatian和23分别封装到obj2(self)的name和age属性中

self是一个形式参数,当执行obj1 = Foo('caoxiaojian','24')时,self等于obj1,同理执行obj2的时候,self等于obj2。所以,内容其实被封装到了对象obj1和obj2中,每个对象中都有name和age属性,在内存中保存下来

B:从某处调用被封装的内容

调用被封装的内容时,有两种情况:

1:通过对象直接调用

上图展示了对象obj1和obj2在内存中保存的方式,根据保存格式可以如此调用被封装的内容:对象名.属性名

#!/usr/bin/env python
# coding:utf-8
# 创建类
class Foo:
    def __init__(self,name,age):  #称为构造方法,根据类创建对象时自动执行
        self.name = name
        self.age = age
# 根据类Foo创建对象obj1
# 自动执行Foo类的 __init__方法
obj1 = Foo('caoxiaojian','24')  # 将caoxiaojian和24分别封装到obj1(self)的name和age属性中
print obj1.name   # 直接调用obj1对象的name属性
print obj1.age    # 直接调用obj1对象的age属性
# 根据类Foo创建对象obj2
# 自动执行Foo类的 __init__方法
obj2 = Foo('caogaotian','23')   # 将caogoatian和23分别封装到obj2(self)的name和age属性中
print obj2.name   # 直接调用obj2对象的name属性
print obj2.age    # 直接调用obj2对象的age属性

2:通过self间接调用被封装的内容

执行类中方法时,需要通过self间接调用被封装的内容

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

#!/usr/bin/env python # coding:utf-8 # 创建类 class Foo:     def __init__(self,name,age):  #称为构造方法,根据类创建对象时自动执行         self.name = name         self.age = age     def detail(self):         print self.name         print self.age # 根据类Foo创建对象 # 自动执行Foo类的__init__方法 obj1 = Foo('caoxiaojian',23) obj1.detail() ''' python默认会将obj1传给self参数,即obj1.detail(obj1), 所以此时方法内部的self = obj1, 即:self.name是caoxiaojian;self.age是23 ''' obj2 = Foo('caogaotian',24) obj2.detail() # 打印结果: # caoxiaojian # 23 # caogaotian # 24

总结:

对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self方式间接获取被封装的被内容。

练习一:

  • 曹小贱,10岁,男,上老男孩python培训
  • 曹小贱,10岁,男,上老男孩基础运维培训
  • 曹小贱,10岁,男,上老男孩架构师培训
  • 曹高田,10岁,男,上老男孩python培训
  • 曹高田,10岁,男,上老男孩基础运维培训
  • 曹高田,10岁,男,上老男孩架构师培训

函数式编程方式:

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

#!/usr/bin/env python # coding:utf-8 # python def python(name,age,sex):     print "%s,%s岁,%s,上老男孩python培训" %(name,age,sex) def base(name,age,sex):     print "%s,%s岁,%s,上老男孩基础运维培训" %(name,age,sex) def high(name,age,sex):     print "%s,%s岁,%s,上老男孩架构师培训" %(name,age,sex)   python('曹小贱',23,'男') base('曹小贱',23,'男') high('曹小贱',23,'男')   python('曹高田',23,'男') base('曹高田',23,'男') high('曹高田',23,'男') ''' 执行结果: 曹小贱,23岁,男,上老男孩python培训 曹小贱,23岁,男,上老男孩基础运维培训 曹小贱,23岁,男,上老男孩架构师培训 曹高田,23岁,男,上老男孩python培训 曹高田,23岁,男,上老男孩基础运维培训 曹高田,23岁,男,上老男孩架构师培训 '''

面向对象编程方式:

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 33 34

#!/usr/bin/env python # coding:utf-8 # 创建类 class Foo:     def __init__(self,name,age,sex):  #称为构造方法,根据类创建对象时自动执行         self.name = name         self.age = age         self.sex = sex     def python(self):         print "%s,%s岁,%s,上老男孩python培训" %(self.name,self.age,self.sex)     def base(self):         print "%s,%s岁,%s,上老男孩base培训" %(self.name,self.age,self.sex)     def high(self):         print "%s,%s岁,%s,上老男孩架构师培训" %(self.name,self.age,self.sex) # 根据类Foo创建对象caoxiaojian # 自动执行Foo类的 __init__方法 caoxiaojian = Foo('曹小贱',23,'男') caoxiaojian.python() caoxiaojian.base() caoxiaojian.high()   caogaotian = Foo('曹高田',24,'男') caogaotian.python() caogaotian.base() caogaotian.high() ''' 打印结果: 曹小贱,23岁,男,上老男孩python培训 曹小贱,23岁,男,上老男孩base培训 曹小贱,23岁,男,上老男孩架构师培训 曹高田,24岁,男,上老男孩python培训 曹高田,24岁,男,上老男孩base培训 曹高田,24岁,男,上老男孩架构师培训 '''

总结:

如果使用函数式编程,需要在每次执行函数时传入相同的参数,如果参数多的话,又需要粘贴复制了。。。;而对于面向对象只需要在创建对象时,将所有的参数封装到当前的对象中,之后再次使用时,通过self间接去当前对象中取值即可

二:继承

继承:子可以继承父的内容

例如:

   动物:吃、喝、拉、撒

      猫:吃(继承动物的功能)

      狗:喝(继承动物的功能)

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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

#!/usr/bin/env python # coding:utf-8 # 创建动物类 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.bread = '猫'     def cry(self):         print "喵喵喵喵喵喵喵喵" class dog(animal):     def __init__(self,name):         self.name = name         self.bread = '狗'     def cry(self):         print "汪汪汪汪汪汪汪汪汪汪汪汪" # 根据类cat创建对象obj1 # 自动执行cat类的 __init__方法 obj1 = cat('小花猫') obj1.eat() obj1.cry()   obj2 = cat('黑猫警长') obj2.drink() obj2.cry()   obj3 = dog('哈士奇') obj3.shit() obj3.cry() ''' 打印结果: 小花猫 吃吃吃 喵喵喵喵喵喵喵喵 黑猫警长 喝喝喝 喵喵喵喵喵喵喵喵 哈士奇 拉拉拉 汪汪汪汪汪汪汪汪汪汪汪汪 '''

总结:

对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需要继承父类而不必一一实现每一个方法。

多继承???

  • 是否可以继承多个类
  • 如果继承的多个类每个类中都定了相同的函数,那么哪一个会被继承使用?

1:Python的类可以继承多个类,Java和C#中则只能继承一个类

2:Python的类如果继承多个类,那么其寻找方法的方式有两种:深度优先和广度优先

  • 当类是经典类时,多继承情况下,会按照深度优先方式查找
  • 当类是新式类时,多继承情况下,会按照广度优先方式查找

经典类和新式类区别:当前类或者父类继承了object类,那么该类便是新式类,否则就是经典类

实例一:经典类

#!/usr/bin/env python
# coding:utf-8
class D:
    def bar(self):
        print 'D.bar'
class C(D):
    def bar(self):
        print 'C.bar'
class B(D):
    def bar(self):
        print 'B.bar'
class A(B, C):
    def bar(self):
        print 'A.bar'
a = A()
a.bar()
# 打印结果:A.bar

总结:

1:执行bar方法时首先去A类中找,如果A类中没有,则去B类中找,如果没有,再去D类中找,如果没有,再去C类中找,如果找不到,则报错

2:查找的顺序:A===>B===>D===>C

3:一旦找到,则寻找过程立即中断,不再继续寻找

实例二:新式类

#!/usr/bin/env python
# coding:utf-8
class D(object):
    def bar(self):
        print 'D.bar'
class C(D):
    def bar(self):
        print 'C.bar'
class B(D):
    def bar(self):
        print 'B.bar'
class A(B, C):
    def bar(self):
        print 'A.bar'
a = A()
a.bar()
# 打印结果:A.bar

总结:

1:执行bar方法时首先去A类中找,如果A类中没有,则去B类中找,如果没有,再去C类中找,如果没有,再去D类中找,如果找不到,则报错

2:查找的顺序:A===>B===>C===>D

3:一旦找到,则寻找过程立即中断,不再继续寻找

三:多态

python不支持多态并且也用不到多态,多态的概念是应用于Java和C#这类强类型语言中,而Python崇尚“鸭子类型”

鸭子类型:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

#!/usr/bin/env python # coding:utf-8 class F1:     pass 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)