Python学习笔记 7--剖析面向对象编程

python面向对象编程

1. 编程方式分类:

  • 面向过程:根据业务逻辑从上到下写垒代码,初学者容易接受
  • 面向函数:将某功能代码封装到函数中,日后便无需重复编写,使用时仅调用函数即可。
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强…”

2.创建类和对象

  • 面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。

    • 类就是一个模板,模板里可以包含多个函数,函数里实现一些功能

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

来一段代码感受下先

##class people:             ## 经典类
class People(object):       ## 创建类,该类为新式类,object类是所有类的基类/父类
    def __init__(self,name,age):    # 构造函数,当实例化对象时自动调用;
        self.name = name            # 属性
        self.age = age

    def run(self):                  # 方法
        print "running...."

    def __del__(self):
        print "deleteing......"     # 析构函数,删除实例化对象时自动调用;

class Student(People):              # Student是子类,继承People这个父类;
    def study(self):                    # 方法
        print "study...."

p1 = People("zhangsan",18)      ##根据类People创建对象p1
s1 = Student("lisi",16)
p1.run()                ##执行run方法
s1.study()
  • class是关键字,表示类
  • 创建对象,类名称后加括号即可
  • 类中的函数第一个参数必须是self
  • 类中定义的函数叫做 “方法”

面向对象的三大特性

1.封装

封装:把内容统一放在一个地方,看成一个整体,(实例化对象self和类的属性绑定在一起),以后再去调用被封装在某处的内容;

  • 访问封装内容的两种方式:
    • 通过self去访问封装的内容;(self.name)
    • 通过实例化的对象名去访问封装的内容;
      p1 = People(“zhangsan”,18)
      p1.age

2. 继承

继承:子承父业

  • 对于面向对象的继承来说,其实就是将多个类共有的属性和方法提取到父类中,子类仅需继承父类,而不必每个子类中去一一实现每个方法或者定每个属性,上面的代码中 name,age是人共有的属性,run()是人共有的方法,我们把它提取到类People中,类Student只需继承People类,就拥有了name,age属性和run()方法,而不必在Student类中重新定义这些属性和方法
  • 新名词:基类/派生类, 父类/子类, 新式类和经典类
    • 派生类 和 基类 ,他们与子类和父类只是叫法不同而已
  • 多继承:

    • Python的类可以继承多个类,Java和C#中则只能继承一个类
    • 如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢

      • Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
      • 当类是经典类时,多继承情况下,会按照深度优先方式查找
      • 当类是新式类时,多继承情况下,会按照广度优先方式查找
    • 新式类: 广度优先继承;(python2.x和python3.x均支持)

    • 经典类:深度优先继承;(python2.x支持,python3.x没有经典类)
class C1:           ##经典类
    pass
class C2(C1):       ##C2是经典类
    pass
class N1(object):   ##新式类
    pass
class N2(N1):       ##N2是新式类
    pass
  • 注意:
    类的方法中可以传递一个对象;
    这里写图片描述
class D:        ##经典类

    def show(self):
        print 'D.show'

class C(D):

    def show(self):
        print 'C.show'

class B(D):

    def show(self):
        print 'B.show'

class A(B, C):

    def show(self):
        print 'A.show'

a = A()
a.show()
# 执行show方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
# 所以,查找顺序:A --> B --> D --> C
# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
class D(object):        ##新式类

    def show(self):
        print 'D.show'

class C(D):

    def show(self):
        print 'C.show'

class B(D):

    def show(self):
        print 'B.show'

class A(B, C):

    def show(self):
        print 'A.show' 
a = A()
a.show()
# 执行show方法时
# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
# 所以,查找顺序:A --> B --> C --> D
# 在上述查找show方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了

3. 多态

  • 类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法:
class Person(object):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
    def whoAmI(self):
        return 'I am a Person, my name is %s' % self.name

class Student(Person):
    def __init__(self, name, gender, score):
        super(Student, self).__init__(name, gender)
        self.score = score
    def whoAmI(self):
        return 'I am a Student, my name is %s' % self.name

class Teacher(Person):
    def __init__(self, name, gender, course):
        super(Teacher, self).__init__(name, gender)
        self.course = course
    def whoAmI(self):
        return 'I am a Teacher, my name is %s' % self.name

在一个函数中,如果我们接收一个变量 people,则无论该 x 是 Person、Student还是 Teacher,都可以正确打印出结果:


def Who_Am_I(people):
    print people.whoAmI()

p = Person('Tom', 'Male')
s = Student('Tim', 'feMale', 98)
t = Teacher('Laoli', 'Male', 'linux')

Who_Am_I(p)
Who_Am_I(s)
Who_Am_I(t)
运行结果:

I am a Person, my name is Tom
I am a Student, my name is Tim
I am a Teacher, my name is Laoli
这种行为称为多态。也就是说,方法调用将作用在 people的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。
  • 如果子类调用的方法,子类没有,父类有,运行父类;
  • 如果子类调用的方法,子类有,父类也有,只运行子类的;

=======================未完待续=======================

面向对象进阶

  • 类变量,全局变量,在内存中只存储一份;
  • 普通的对象属性,每个对象中都需要存储一份;

方法

  • 实例化方法:第一个参数为self(实例化本身);
  • 类方法:第一个参数是cls(类本身);通过@classmethod装饰器实现;
  • 静态方法:第一个参数既不是self也不是cls;通过@staticmethod方法实现;

特殊属性

类的特殊成员

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值