zoukankan      html  css  js  c++  java
  • python 面向对象

       属性

              实例变量:   __init__需要初始化的变量,实例变量作用域就是实例本身
              类变量:      写在class全局的变量
              私有属性 ,如下:这样的话通过实例无法调用这个属性 。
              

              当要访问私有属性的时候,可以新建一个方法,内部方法是可以调用私有属性的,然后通过调用这个方法来获取私有属性的值:

              

              print(r1.show_status())

              如果实例调用变量,实例变量和类变量都定义了相同变量,那么优先去实例变量,没有再找类变量。 

              

        方法       

              构造方法:
                    def  __init__(self):
                           self.name = name
              析构函数,在实例释放(删除实例del 或者实例运行结束),销毁的时候自动执行的,通常做一些收尾工作。如:关闭一些数据库链接,关闭打开的临时文件
                    def  __del__(self):
                           do something
     
              私有方法,定义普通方法的时候前面加两个下划线 
     

    对象

           实例化一个类之后得到的对象
     

    封装

          把一些功能的实现细节不对外暴露
          第一个层面的封装(什么都不用做):创建类和对象会分别创建二者的名称空间,我们只能用类名.或者obj.的方式去访问里面的名字,这本身就是一种封装。
          第二个层面的封装:类中把某些属性和方法隐藏起来(或者说定义成私有的),只在类的内部使用、外部无法访问,或者留下少量接口(函数)供外部访问。 
     

    继承

          代码重用
          单继承
          多继承
                     2.7经典类(class People()),深度优先,新式类(class People(object)),广度优先
                     3.x广度优先 
          
     
     
     继承例子:
    class Peolpe():
    
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def talk(self):
            print("%s is talking..."%self.name)
    
        def sleep(self):
            print("%s is sleeping..."%self.name)
    
    class Man(Peolpe): ##此处继承
        pass
    
    m1 = Man("liyang",22)
    m1.sleep()

           

    继承重用

    class Peolpe():
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def talk(self):
            print("%s is talking..."%self.name)
        def sleep(self):
            print("%s is sleeping..."%self.name)
    
    class Man(Peolpe): ##此处继承
        def eat(self):
            print("%s is eating"%self.name)
        def sleep(self):
            Peolpe.sleep(self) ##此处调用父类方法,如果没有这行,sleep方法会重写,不会执行父类方法
            print("man also is sleeping")
    
    m1 = Man("liyang",22)
    m1.sleep()

    如果子类要新增初始化参数呢,要修改一下子类

    class Man(People): ##此处继承
        def __init__(self,name,age,location):
            People.__init__(self,name,age) ##继承父类初始化参数
            self.location = location  ##新加一个参数

    或者

    class Man(People): ##此处继承
        def __init__(self,name,age,location):
            #People.__init__(self,name,age) ##继承父类初始化参数
            super(Man,self).__init__(name,age)  ##使用super内置函数,新式写法
            self.location = location  ##新加一个参数

    多继承:

    # -*- coding:utf-8 -*-
    # Author:Brownyangyang
    
    class People(): #经典类
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def talk(self):
            print("%s is talking..."%self.name)
        def sleep(self):
            print("%s is sleeping..."%self.name)
    
    class Relation(object): #新式类写法,经典类没有object
        def make_friends(self,obj):  #obj自定义对象,和谁交朋友。self是一个对象,obj也是一个对象,这么理解
            print("%s is makeing friends with %s"%(self.name,obj.name))
            #self.name是People那边继承过来的,obj 是定义的一个实例
            #继承People()已经把name初始化了,所以继承Relation()的时候可以直接调用name,这里不需要再初始化name
    
    class Man(People,Relation): ##此处继承
        def __init__(self,name,age,location):
            #People.__init__(self,name,age) ##继承父类初始化参数
            super(Man,self).__init__(name,age)
            self.location = location  ##新加一个参数
    
        def eat(self):
            print("%s is eating"%self.name)
        def sleep(self):
            People.sleep(self) ##此处调用父类方法,如果没有这行,sleep方法会重写,不会执行父类方法
            print("man also is sleeping in %s"%self.location)
    
    class Woman(People,Relation):
        def get_birth(self):
            print("%s is borning the baby"%self.name)
    
    m1 = Man("xiaoming",22,"nantong")
    
    w1 = Woman("xiaohong",32)
    m1.make_friends(w1)

    结果:xiaoming is makeing friends with xiaohong

     

    多态

            接口重用,一种接口多次实现 
     
     

    方法修饰

     
    静态方法 @staticmethod 
           只是名义上归类管,实际上跟类没什么关系了,实际上在静态方法里访问不了类或实例中的任何属性
     
    类方法@classmethod
           只能访问类变量,不能访问实例变量
     
    属性方法@property
          把一个方法变成一个静态属性 
     
     
    静态方法实例
    class Dog(object):
        def __init__(self,name):
            self.name = name
    
        def eat(self,food):
            print("%s is eating %s"%(self.name,food))
    
    d = Dog("liyang")
    d.eat("beaf")

    结果:liyang is eating beaf

    使用静态方法 @staticmethod 后

    class Dog(object):
        def __init__(self,name):
            self.name = name
    
        @staticmethod
        def eat(self,food):
            print("%s is eating %s"%(self.name,food))
    
    d = Dog("liyang")
    d.eat("beaf")

    因为不能调用实例变量和类变量,上面执行会报错:

    类方法实例

    class Dog(object):
        def __init__(self,name):
            self.name = name
    
        def eat(self):
            print("%s is eating "%self.name)
    
    d = Dog("liyang")
    d.eat()

    运行结果:liyang is eating  

    使用类方法@classmethod后:
    class Dog(object):
        def __init__(self,name):
            self.name = name
    
        @classmethod  ##只加了这个
        def eat(self):
            print("%s is eating "%self.name)
    
    d = Dog("liyang")
    d.eat()

    因为@classmethod 只能访问类变量,不能访问实例变量,报错如下:

    如果我在类变量再定义一个那么,如下:

    class Dog(object):
        name=“xiaoming”  ##在这里新定义一个name
        def __init__(self,name):
            self.name = name
    
        @classmethod  ##只加了这个
        def eat(self):
            print("%s is eating "%self.name)
    
    d = Dog("liyang")
    d.eat()

    结果:xiaoming is eating 

    说明类方法只能访问类变量,不能访问实例变量

    属性方法实例:

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        @property   ##属性方法
        def eat(self):
            print("%s is eating "%self.name)
    
    d = Dog("liyang")
    d.eat()

    把一个方法变成一个静态属性,那调用方法就变了,如果不修改调用方法就会报错:

    只需要 把d.eat() 改成d.eat  就可以了。

    最后:

    被property装饰的属性会优先于对象的属性被使用,而被propery装饰的属性,分成三种:property、被装饰

    的函数名.setter、被装饰的函数名.deleter(都是以装饰器的形式)。

    class people: #定义一个人的类
        def __init__(self,name,sex):
            self.name = name
            self.sex = sex #p1.sex = "male",遇到property,优先用property
    
        @property #查看sex的值
        def sex(self):
            return self.__sex #返回正真存值的地方
    
        @sex.setter #修改sex的值
        def sex(self,value):
            if not isinstance(value,str): #在设定值之前进行类型检查
                raise TypeError("性别必须是字符串类型") #不是str类型时,主动抛出异常
            self.__sex = value #类型正确的时候,直接修改__sex的值,这是值正真存放的地方
                #这里sex前加"__",对sex变形,隐藏。
    
        @sex.deleter #删除sex
        def sex(self):
            del self.__sex
    
    p1 = people("egon","male") #实例化对象p1
    print(p1.sex) #查看p1的sex,此时要注意self.sex的优先级
    p1.sex = "female" #修改sex的值
    print(p1.sex) #查看修改后p1的sex
    print(p1.__dict__) #查看p1的名称空间,此时里面有sex
    del p1.sex #删除p1的sex
    print(p1.__dict__) #查看p1的名称空间,此时发现里面已经没有sex了

    结果:

    male
    female
    {'name''egon''_people__sex''female'}
    {'name''egon'}
  • 相关阅读:
    org.Hs.eg.db
    Error in readRDS(dest) : error reading from connection
    R语言中的特殊值 NA NULL NaN Inf
    C#转Java之路之三:多线程并发容器即线程安全的容器
    C#转Java之路之二:多线程原子变量
    C#转Java之路之一:线程
    H5 input type="search" 不显示搜索 解决方法
    陪你在路上...我却渐行渐远
    Extjs使用 RestfulWebApi +Token验证小结
    Oracle 10g的备份与还原
  • 原文地址:https://www.cnblogs.com/brownyangyang/p/9060207.html
Copyright © 2011-2022 走看看