• python基础之面向对象02


    ---继承

      当我们定义完成某个类时,可以再定义一个新类,新类可以继承第一个类。新类被称为子类,而被继承的类称为父类/基类/超类。

      继承就是子类继承父类的属性和方法(注意是类属性和类方法)。

      继承可以使子类使用父类中的方法,也可以在子类中新定义某个方法,或者在子类中覆盖父类的方法。

      来看一个实例:

    复制代码
    class animal(object):    #定义一个动物类
        def running(self):
            print('running....')
    class dog(animal):       #定义一个狗类,且狗类继承动物类
        def wangwang(self):
            print('wang! wang!')
    
    
    xiaohei=dog()
    xiaohei.running()
    xiaohei.wangwang()
    #结果
    running....
    wang! wang!
    复制代码

      我们可以看到,在上面的例子中,dog类继承animal类后,就不需要再重新定义running方法,可以直接调用animal中的running方法。这就是继承的优点之一。
      如果我们在dog类中也定义一个running方法会怎样?

    复制代码
    class animal(object):
        def running(self):
            print('running....')
    class dog(animal):
        def wangwang(self):
            print('wang! wang!')
        def running(self):
            print('dog is running')
    #结果
    dog is running       #父类的方法被子类同名的方法覆盖
    wang! wang!
    复制代码

      也就是,子类中的方法会覆盖父类中同名的方法!

    子类如何执行父类的构造函数?

      1  super(Son, self).__init()

      2  Father.__init__(self)

     View Code

    ---多继承

     所谓多继承就是指一个子类可以继承多个父类。大家可能会问:

      1 怎么样才能实现多继承?

      2 如果每个父类都有一个名称相同的方法,当子类调用该方法时最终调用的是哪一个?

      1 首先来看第一个问题,怎么样才能实现多继承?

    复制代码
    class animal(object):
        def running(self):
            print('running....')
    class mammal(object):
        def grow(self):
            print('吃奶')
    class dog(animal,mammal):     #<-----------在括号中加入父类名称,并以逗号分隔即可
        def wangwang(self):
            print('wang! wang!')
        def running(self):
            print('dog is running')
    
    xiaohei=dog()
    xiaohei.running()
    xiaohei.wangwang()
    xiaohei.grow()
    #结果
    dog is running
    wang! wang!
    吃奶
    复制代码

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

      2 再来看第二个问题:如果每个父类都有一个名称相同的方法,当子类调用该方法时最终调用的是哪一个?或者说继承顺序是怎样的?

      在回答这个问题之前,我们需要先了解经典类和新式类。

      什么是经典类什么是新式类?

    class  class_name:  #经典类的定义方法
        pass
    
    class  class_name(object):  #新式类的定义方法
        pass

      新式类较之经典类添加了很多功能,所以现在推荐用新式类。

      在Python3中不管是新式类还是经典类继承顺序都是深度优先

    复制代码
    
    
    class a(object):
    def f(self):
    print('a')
    self.f1()
    def f1(self):
    print('a-f1')

    class b(object):
    def f1(self):
    print('b')

    class c(a):
    def f1(self):
    print('c')

    class d(b):
    def f(self):
    print('d')

    class e(c,d):
    def f1(self):
    print('e')

    e1 = e()
    e1.f()
     
    复制代码

     

    但有个特殊情况:

      如果A和B都all类的子类,则找完A以后不会找all,而是去找D。

    我们可以总结出Python多继承时的优先顺序:

      1  本身最大,先从自身查找

      2  从左到右优先级依次降低,深度优先

      3  若左父类与右父类的上层存在共同的父类,则将共同的父类及其上层移动到右父类的深度级别中

    ---方法

      python中的方法包括普通方法/静态方法/类方法。但静态方法和类方法并不常用。

      所有方法均属于类属性,也就是在内存中只有一份

      普通方法:只能由实例调用,最少有一个self参数

      静态方法:不需实例化就可以调用,没有默认参数

      类方法:不需实例化就可以调用。最少有一个cls参数

     View Code

    ---属性

      之前我们讲过,在类中的某个变量前加上两个下划线,就可以将这个变量“隐藏”起来,使其外部不可见。

    复制代码
    class atm00(object):
        def __init__(self,money):
            self.money=money
        def show_money(self):
            print('the atm has %s¥ '%self.money)
    
    a=atm00(100)
    a.show_money()
    a.money=120
    a.show_money()
    #结果
    the atm has 100¥ 
    the atm has 120¥ 
    #很明显,我们可以直接在外部给a.money赋值,这样虽然操作简单,但是我们无法验证用户输入的money是否合法
    复制代码

    这时,我们可以这样修改:

    复制代码
    class atm01(object):
    
        def __init__(self,money):
            self.__money=money
        def show_money(self):
            print('the atm has %s¥ '%self.__money)
        def set_money(self,money):                            #当修改money时,还可以检测用户输入的值是否合法
            if not isinstance(money,int):
                print("money's value must be interger")
            else:
                self.__money=money
    a=atm01(100)
    a.show_money()
    a.set_money(120
    复制代码

      通过修改,我们让代码更健壮更安全,但是却没有之前在外部直接赋值时的便捷了。有没有一种方法,即可以在外部直接赋值,有可以检测用户输入值的合法性呢?这里我们就要用到属性了!

    复制代码
    class atm01(object):
        def __init__(self,money_value):
            self.__money=money_value
        @property                            #第一种属性
        def money(self):
            return self.__money
        @money.setter              #第二种属性
        def money(self,money_value):
            if not isinstance(money_value,int):
                print("money's value must be interger")
            else:
                self.__money=money_value
        @money.deleter              #第三种属性
        def money(self):
            print('no money')
    
    a=atm01(100)
    print(a.money)
    a.money=120
    print(a.money)
    del a.money
    #结果
    100
    120
    no money
    复制代码

     上面的代码可能会看不懂,没关系,上面仅仅是用来说明属性的重要性,接下来我们来正式的讲解一下属性。

      如何定义属性?

    属性共有三种。

    首先来看第一种属性:

    复制代码
    class test(object):
      def step1(self):
            pass
      @property           #定义时,在普通方法的基础上添加 @property 装饰器,该方法就成为属性
        def step2(self):
            return 'hello world'
    a=test()
    print(a.step2)
    #结果
    hello world
    复制代码

      注意两点:

        1  属性中仅能包含一个self参数

        2  调用属性时,不需要加括号

    第二种和第三种属性:

    复制代码
    # ############### 定义 ###############
    class Goods(object):
    
        @property
        def price(self):
            print '@property'
    
        @price.setter
        def price(self, value):
            print '@price.setter'
    
        @price.deleter
        def price(self):
            print '@price.deleter'
    
    # ############### 调用 ###############
    obj = Goods()
    
    obj.price          # 执行@property 修饰的 price 方法,并获取方法的返回值
    
    obj.price = 123    # 执行@price.setter 修饰的 price 方法,并将  123 赋值给方法的参数
    
    del obj.price      # 执行@price.deleter 修饰的 price 方法
    复制代码

    总结一下,这三种属性作用分别为显示,修改,删除。

  • 相关阅读:
    SSM实现mysql数据库账号密码加密连接
    获取系统相关信息 (CPU使用率 内存使用率 系统磁盘大小)
    JavaWeb(一) / /* /**的区别
    IDEA(一) 使用IDEA搭建SSM框架项目
    Mysql连接数据库异常汇总【必收藏】
    Java代理模式及动态代理详解
    SpringBoot集成Thymeleaf
    设计师,程序员,当心字体侵权
    Java开发神器Lombok使用详解
    日期格式化跨年bug,是否与你不期而遇?
  • 原文地址:https://www.cnblogs.com/yezuhui/p/6860365.html
Copyright © 2020-2023  润新知