zoukankan      html  css  js  c++  java
  • python 面向对象编程学习总结

    面向对象是个抽象的东西,概念比较多,下面会一一介绍。

    一、类和实例

    类(Class)和实例(Instance)是面向对象最重要的概念。

    类是指抽象出的模板。实例则是根据类创建出来的具体的“对象”,每个对象都拥有从类中继承的相同的方法,但各自的数据可能不同。

    class Student(object):
        pass
    
    kate = Student()

    关键字class后面跟着类名,类名通常是大写字母开头的单词,紧接着是(object),表示该类是从哪个类继承下来的。通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承下来的类。

    Student 就是类名,kate 就是Student()的实例,类只有实例化以后才能使用。

    二、构造函数,析构函数,类变量,实例变量

    构造函数:__init__(self,name,age,sex), 这个方法就是构造函数,在实例化的时候自动调用。所有如果这个函数内有打印的方法,当kate实例出来的时候会打印里面的信息。

    __init__方法的第一个参数永远都是self,表示创建实例本身,在__init__方法内部,可以把各种属性绑定到self,因为self指向创建的实例本身。

    有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。

    析构函数:__del__(self), 这个方法就是析构函数,是在实例被销毁时自动调用的。

    类变量: country = 'China' , 类变量不需要实例,可以直接使用, 如line 14

    实例变量: self.name = name, self.name 这种形式就是实例变量,需要实例化后才能使用, 如 line15就会报错,需要实例化line16的kate, 才能使用name, age, sex

    可以自由地给一个实例变量绑定属性,比如,给实例kate绑定一个language属性。

    kate.language = '中文'
    print(kate.language) #中文

    和普通函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别。比如school函数只需要传city就可以了。

    kate.school('北京') #凯特在北京上学

    下面是具体的代码段例子。

     1 class Person(object):
     2     country = 'China' #类变量,不需要实例化,可以直接用
     3     def __init__(self,name,age,sex):#构造函数,实例化的使用自动调用
     4         self.name = name #实例变量,必须实例化之后才能用,也叫成员变量
     5         self.age = age
     6         self.sex =sex
     7     def say_my_country(self):
     8         print(self.country)#类变量可以在类里作为属性使用
     9     def school(self,city):
    10         self.city = city
    11         print('%s在%s上学' %(self.name,self.city))
    12     def __del__(self):#析构函数,实例销毁的时候自动调用
    13         print('实例销毁的时候自动调用')
    14 print(Person.country)#类变量,不需要实例化,可以直接用
    15 #print(Person.name)#实例变量,必须实例化之后才能用,AttributeError: type object 'Person' has no attribute 'name'
    16 kate = Person('凯特',18,'')
    17 print(kate.name)
    18 print(kate.age)
    19 print(kate.sex)
    20 print(kate.country) #China
    21 kate.say_my_country() #China
    22 kate.language = '中文' 
    23 print(kate.language) #中文
    24 kate.school('北京') #凯特在北京上学

    三、访问限制

    Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样就隐藏了内部的复杂逻辑。

    1 kate = Person('凯特',18,'')
    2 kate.name = '王菲'
    3 print(kate.name)

    如果加这句代码line2,kate.name = '王菲', 这样执行line3就会打印王菲,而不是凯特,name会修改了。

    四、私有变量,私有函数,静态方法,类方法

     

    私有变量:self.__host = host ,只能在类里使用,如果执行line31会报错 AttributeError: 'MyRedis' object has no attribute '__host'

    私有函数:def __conn_redis(self),只能在类里使用,执行line32会报错 AttributeError: 'MyRedis' object has no attribute '__conn_redis'

    静态方法: 需要加  @staticmethod,不需要实例化就能直接用,其实和类没有什么关系,就是一个普通的函数,写在了类里面而已,也用不了self的那些东西,也调用不了类里的其他函数

    类方法:需要加 @classmethod,不需要实例化就能直接用,它比静态方法高级一点,它可以使用类变量和类方法, 如函数 class_fun(cls)

     1 import redis
     2 class MyRedis():
     3     hi= '哈哈'
     4     def __init__(self,host,db,password='',port=6379):
     5         self.__host = host # 私有变量,只能在类里使用
     6         self.passwd = password
     7         self.port = port
     8         self.db = db
     9         #self.conn_redis()
    10         self.__conn_redis()
    11     # def conn_redis(self):
    12     #     self.conn = redis.Redis(host=self.__host,db=self.db,password=self.passwd,port=self.port)
    13     def __conn_redis(self): #私有函数,只能在类里使用
    14         self.conn = redis.Redis(host=self.__host,db=self.db,password=self.passwd,port=self.port)
    15     def get(self,k):
    16         print('__host...',self.__host)
    17         return self.conn.get(k).decode()
    18 
    19     @staticmethod #静态方法
    20     def other():
    21         print('我是other')
    22     @classmethod #类方法,也不需要实例化,直接就能用,它比静态方法高级一点,它可以使用类变量和类方法
    23     def class_fun(cls):
    24         print(cls.hi) #可以调用类变量
    25         cls.class_fun2()#可以调用类方法
    26     @classmethod
    27     def class_fun2(cls):
    28         print('类方法2')
    29 
    30 r = MyRedis('localhost',3)
    31 # print(r.__host) #AttributeError: 'MyRedis' object has no attribute '__host'
    32 #r.__conn_redis() #AttributeError: 'MyRedis' object has no attribute '__conn_redis'
    33 print(r.get('kate11'))
    34 MyRedis.other() #静态方法不需要实例化
    35 MyRedis.class_fun()

    五、继承

    在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

    比如,我们已经编写了一个名为Animal的class,有一个run()方法可以直接打印一句话,然后新建一个叫Dog的类,继承了Animal类。

    所以Dog可以用Animal类里的函数run(), eat(),同时自己也可以定义自己的函数。

     @property ,这是个装饰器,把函数变成一个属性方法,如果这个方法没有入参的话,那就可以变成一个属性方法。

    在使用的时候可以如下面代码所示的 b.protect, 而不是像其他的方法一样加(), 如 b.bite()

     1 class Animal(object):
     2     def run(self):
     3         print('running...')
     4     def eat(self):
     5         print('eating...')
     6 
     7 class Dog(Animal):
     8     def run(self):
     9         print('dog is running')
    10     def bite(self):
    11         print('dog will bite people.')
    12     @property
    13     def protect(self):
    14         print('dog will protect people.')
    15 a = Animal()
    16 a.run()
    17 a.eat()
    18 b = Dog()
    19 b.run()
    20 b.eat()
    21 b.bite()
    22 b.protect #属性方法, dog will protect people.
  • 相关阅读:
    centos7安装rlwrap
    Linux CentOS 7的图形界面安装(GNOME、KDE等)
    在oracle下我们如何正确的执行数据库恢复
    Viewer.js 图片预览插件使用
    深拷贝和浅拷贝
    ES6 export,import报错
    Yarn 命令详解
    npm命令 VS yarn命令
    Windows下nginx作为静态资源服务器使用
    关于Vue脚手架写法的问题
  • 原文地址:https://www.cnblogs.com/nancyzhu/p/8469751.html
Copyright © 2011-2022 走看看