zoukankan      html  css  js  c++  java
  • 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)

    class Animal(object):
        name = 'ahah'
        def __init__(self):
            self.a = 'animal'
    
    class Cat(Animal):
        def __init__(self):
            super(Cat,self).__init__()
            # Animal.__init(self)
            self.b = 'cat'
    
    c1 = Cat()
    print(c1.a)  #animal
    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参数

    class test(object):
    
        def show1(self):
            print('普通方法')
        @staticmethod             #静态方法
        def show2():
            print('静态方法')
        @classmethod              #类方法
        def show3(cls):
            print('类方法')
    
    #不实例化
    test.show2()
    test.show3()
    print('------------分隔-------------')
    #实例化
    a=test()
    a.show1()
    a.show2()
    a.show3()
    
    #结果
    静态方法
    类方法
    ------------分隔-------------
    普通方法
    静态方法
    类方法
    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 方法

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

  • 相关阅读:
    HDU 3681 Prison Break 越狱(状压DP,变形)
    POJ 2411 Mondriaan's Dream (状压DP,骨牌覆盖,经典)
    ZOJ 3471 Most Powerful (状压DP,经典)
    POJ 2288 Islands and Bridges (状压DP,变形)
    HDU 3001 Travelling (状压DP,3进制)
    POJ 3311 Hie with the Pie (状压DP)
    POJ 1185 炮兵阵地 (状压DP,轮廓线DP)
    FZU 2204 7
    POJ 3254 Corn Fields (状压DP,轮廓线DP)
    ZOJ 3494 BCD Code (数位DP,AC自动机)
  • 原文地址:https://www.cnblogs.com/MnCu8261/p/5534135.html
Copyright © 2011-2022 走看看