zoukankan      html  css  js  c++  java
  • class面向对象编程学习笔记

    1、__ intit__(self,x,xx,xxx,...)
      采用__ init__(self,,xx,xxx,xxxx,...)方法在创建实例时就把属性绑上去,第一个参数一定是self,self指向创建的实例本身
      和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,其他并没有什么差别。但是采用对象编程的一个特点就是数据封装
      和静态语言不同,python允许对实例变量绑定任何数据,比如原本Student类中只有name,score两个属性,但是bart.age=18,可以得到一个新的age属性,但是也只是这个实例有这个属性,Student类中的其他实例并不会有这个age属性。

    2、访问限制
      私有变量:在属性前面加两个下划线,如 _ _ name
      特殊变量:属性名称前后都加两个下划线,如 _ _ name _ _ ,特殊变量在外部可以直接访问,不是私有变量
      私有变量是习惯默认外部不能访问,但是python中在外部其实是可以访问的,但是python解释器会改变名称,如 _ _ name,python会改成_ class名__name(不同解释器的名字可能会不同,所以最好不要在外部直接访问)
      如果想在外部访问私有变量,可以采用下面这种方法:

    class Student(object):
      pass...
    
      def get_name(self):
        return self.__name
    
      def get_score(self):
        return self.__score

      如果允许外部修改,可以采用下面方法:

    class Student(object):
      ...
      def set_score(self, score):
        self.__score = score

      虽然当取消私有变量时可以直接修改,但是采用这种方法可以对参数进行检查,防止传入无效参数,比如上面的例子,可以在set_score函数里面判断分数是否在0——100。

    class Student(object):
      def __init__(self,name,score):
        self.__name=name    #加__就把变量变为私有的了,外部不能访问
        self.__score=score
      def print_score(self):
        if self.__score>=90:
          print(self.__name,self.__score,'A')
        elif self.__score>=60:
          print('%s:%s %s' % (self.__name,self.__score,'B'))
        else:
          print('%s:%s %s'%(self.__name,self.__score,'C'))
          
    bart = Student('bart',99)
    lisa=Student('lisa',20)
    lili=Student('lili',66)
    bart.print_score()
    lisa.print_score()
    lili.print_score()
    
    print(bart._Student__name)  #私有变量其实在外部是可以访问到的,只是python解释器自动改成了_Stident__name,但是最好不要这样做,因为不同版本的python解释器可能会把__name改成不同的名字
    
    bart.__name='new name'
    print(bart.__name)        #因为python解释器把__name改了名字,所以其实这里的bart.__name其实是一个新的变量,原来的bart.__name现在叫做bart._Student__name
    print(bart._Student__name)  

    结果如下:

     

    3、继承和多态

        所有的类最终都会继承object类,所以,没有直接继承的类时,就写class xx(object),有直接继承的类时,括号里面就是父类,如class Dog(Animals) (类的名字一般首字母大写)。

    定义一个类就相当于定义了一种数据类型,如:

    a = list() # a是list类型
    b = Animal() # b是Animal类型
    c = Dog() # c是Dog类型


    #判断变量是否是某个类型,可以用 isinstance

    >>> isinstance(a, list)
    True
    >>> isinstance(b, Animal)
    True
    >>> isinstance(c, Dog)
    True

    但是由于Dog是Animals的子类,所以c也是Animals类型:

    >>> isinstance(c, Animal)
    True

        所以当参数是Animals的函数,传入参数为Animals子类的实例时,也是可以运行的,体现了多态性,即当参数为Animals或子类时,实际调用是看当前的具体对象,调用相应的函数或方法,如下例,函数run_twice是以Animals为参数,但是run_twice(Dog()),run_twice(Tortoise())都可以运行,并且是他们对应的run函数:

    class Animal(object):
    def run(self):
    print('Animal is running...')
    
    class Dog(Animal):
    def run(self):
    print('Dog is running...')
    
    class Tortoise(Animal):
    def run(self):
    print('Tortoise is running slowly...')
    
    
    def run_twice(Animal): #其实在python中,这里的参数不一定为Animals类型(鸭子类型),只要有run函数,不管参数是什么,都可以调用,不过具体调用还是看当前对象及相应方法
    Animal.run()
    Animal.run()
    
    >>> run_twice(Animal())
    Animal is running...
    Animal is running...
    >>> run_twice(Dog())
    Dog is running...
    Dog is running...
    >>> run_twice(Tortoise())
    Tortoise is running slowly...
    Tortoise is running slowly...

    但是对于python这样的动态语言来说,继承并没有静态语言严格,即如果不是Animals的子类,只要其中含有run方法,则也可调用run_twice函数:

  • 相关阅读:
    lecture 11.4
    lecture 10.30
    boolean functions and beyon
    lecture10.21
    golang hex to string
    golang中 将string转化为json
    ubuntu16报错: add-apt-repository command not found
    ubuntu16的防火墙关闭
    ubuntu 16 解决错误 manpath: can't set the locale; make sure $LC_* and $LANG are correct
    go get 安装时报 (https fetch: Get https://golang.org/x/crypto/acme/autocert?go-get=1: dial tcp 220.255.2.153:443: i/o timeout)
  • 原文地址:https://www.cnblogs.com/rainbowdawn/p/8016921.html
Copyright © 2011-2022 走看看