• Python学习笔记(五)————面向对象编程


    # 一、类和实例
    # 1、面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,
    # 比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
    #
    # 2、以Student类为例,在Python中,定义类是通过class关键字:
    # class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),
    # 表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用object类,
    # 这是所有类最终都会继承的类。
    #
    # 3、定义好了Student类,就可以根据Student类创建出Student的实例,创建实例是通过类名+()实现的:
    #
    # 4、注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,
    # 因为self就指向创建的实例本身。有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,
    # 但self不需要传,Python解释器自己会把实例变量传进去:
    bart = Student()
    bart        #指向student的实例,每个对象的内存地址不一样
    Student     #这是第一个类
    
    
    #特殊方法“__init__”前后分别有两个下划线
    #1、不能传入空参数要传入除init之外的两个参数
    # __init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,
    # 但self不需要传,Python解释器自己会把实例变量传进去:
    
    
    #数据的封装
    #Student类,就只需要知道,创建实例需要给出name和score,
    # 而如何打印,都是在Student类的内部定义的,这些数据和逻辑被“封装”起来了,
    # 调用很容易,但却不用知道内部实现的细节。
    class Student(Object):
        def __init__(self,name,score):
            self.name = name
            self.score = score
    
    def print_score(self):
        print('%s: %s' % (self.name, self.score))
    
    def get_grade(self):
        if self.score >=90:
            return 'A'
        elif self.score >=60:
            return 'B'
        else:
            return 'C'
    

    # 二、访问限制

    # 内部属性不被外部访问,可以把属性的名称前加上两个下划线__
    # 保证外部代码不能随意访问对象内部 代码更加健壮
    # 使用get 和 set方法来访问设置变量

    #变量的类型
    #__参数/_参数 为私有变量 只能通过 _类名__变量名 来访问,但是根据语法不要随便访问
    #__参数__ 为特殊变量 可以直接访问
    #如当前的调用   
    class Student(object):
        def __init__(self, name, score):
            self.__name = name
            self.__score = score
    
        def get_name(self):
            return self.__name
    
        def get_score(self):
            return self.__score
    
        def print_score(self):
            print('%s: %s' % (self.__name, self.__score))
    
        def set_score(self, score):
                if 0 <= score <= 100:
                    self.__score = score
                else:
                    raise ValueError('bad score')
    
    #如当前的调用
    #1的情况下调用会是这样
    bart = Student('Bart Simpson', 59) #这边的name是_Student__name
    bart.__name='AMy'                  #这边的name是bart.__name
    print(bart.get_name())
    print(bart.__name)
    #此时调用bart.getname(),输出Bart Simpson,student的name并不会被改变
    
    #2的情况下会是这样
    # bart = Student('Bart Simpson', 59)
    # print(bart.__name)
    # #会报错print(bart.__name)
    # #AttributeError: 'Student' object has no attribute '__name'  

     

    习题

    #习题
    #请把下面的Student对象的gender字段对外隐藏起来,用get_gender()和set_gender()代替,并检查参数有效性:
    class Student(object):
        def __init__(self, name, gender):
            self.__name = name
            self.__gender = gender
        def get_name(self):
            return self.__name
        def get_gender(self):
            return self.__gender
    
        def set_gender(self,gender):
            self.__gender = gender
    
        def set_name(self,name):
            self.__name= name
    
    # 测试:
    bart = Student('Bart', 'male')
    if bart.get_gender() != 'male':
        print('测试失败!')
    else:
        bart.set_gender('female')
        if bart.get_gender() != 'female':
            print('测试失败!')
        else:
            print('测试成功!')
    

      

    #三、继承和多态
    #在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承
    #新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)
    class Animal(object):
        def run(self):
            print('Animal is running...')
    
    #子类在继承父类的时候获得了多态
    class Dog(Animal):
        def run(self):
            print('Dog is running...')
    
    class Cat(Animal):
        def run(self):
            print('Cat is running...')
    
    class Tortoise(Animal):
        def run(self):
            print('Tortoise is running...')
    
    #1.子类和父类会是同一种类型
    c=Dog()
    isinstance(c, Animal)   #true
    #run
    
    #2.开闭原则:
    # 对扩展开放:允许新增Animal子类,按照Animal类型进行操作,会自动调用实际类型的run()方法
    # 对修改封闭:不需要修改依赖Animal类型的run_twice函数
    def run_twice(a):
        a.run()
    
    run_twice(Dog())
    run_twice(Cat())
    
    #3.静态语言和动态语言
    #静态语言(如java)    如果需要传入Animal类型 传入对象必须是Animal或者是它的子类,否则无法调用run()方法
    #动态语言(如python)不一定要传入Animal类型 只要保证传入的对象有一个run()方法就可以了
    
    #四、获取对象信息
    #1、type()判断对象类型
    #基本类型
    type(123)
    type('str')
    #函数或类
    type(abs)
    #判断2个变量的type类型是否相同
    type(123)==type(456)
    type(123)==int
    
    #2、isinstance() 判断一个对象是否等于一个函数 ,子类的类型会和父类的一致
    #3、判断数据类型结构
    isinstance((1, 2, 3), (list, tuple))
    
    #4、dir()
    #如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:
    dir('ABC')
    #['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
    
    
    
    #通过内置的一系列函数,我们可以对任意一个Python对象进行剖析,拿到其内部的数据。
    #要注意的是,只有在不知道对象信息的时候,我们才会去获取对象信息。如果可以直接写:
    sum = obj.x + obj.y
    
    
    #判断是否有x属性
    hasattr(obj, 'x')
    #设置一个y属性
    setattr(obj, 'y', 19)
    #获取属性'z',如果不存在,返回默认值404
    getattr(obj, 'z', 404)
    #获取属性'y'
    getattr(obj, 'y')
    # 获取属性'y'
    obj.y
    #获取对象的方法
    #判断有属性power
    hasattr(obj, 'power')
    # 获取属性'power'
    getattr(obj, 'power')
    
    
    
    
    # len('ABC') 和  'ABC'.__len__() 都是获取字符串的长度
    
    
    #假设我们希望从文件流fp中读取图像,我们首先要判断该fp对象是否存在read方法,
    # 如果存在,则该对象是一个流,如果不存在,则无法读取。hasattr()就派上了用场。
    def readImage(fp):
        if hasattr(fp, 'read'):
            return readData(fp)
        return None
    
    #五、实例属性和类属性
    #1、给实例绑定属性
    class Student(object):
        def __init__(self):
            self.name=name
    # s=Student('Bob')
    # s.score=90
    
    #2、给类绑定属性
    class Student(object):
        name = 'Student'
    
    
    s = Student() # 创建实例s
    print(s.name) # 打印name属性为Student,因为实例并没有name属性,所以会继续查找class的name属性,
    
    s.name = 'Michael' # 给实例绑定name属性
    print(s.name) # 打印name属性为Michael,由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
    
    del s.name # 如果删除实例的name属性
    print(s.name) # 打印name属性为Student,再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
    

      

      

      

    声明 欢迎转载,但请保留文章原始出处:) 博客园:https://www.cnblogs.com/chenxiaomeng/ 如出现转载未声明 将追究法律责任~谢谢合作
  • 相关阅读:
    HDU1575--Tr A(矩阵快速幂)
    HDU 2147--HDU 2147(博弈)--我可能做了假题。。。
    新年第一发--HDU1848--Fibonacci again and again(SG函数)
    【转】你真的会二分查找吗?
    windows与ubuntu双系统的安装
    bestcoder#9--1001--Lotus and Characters
    PC端的混合应用通讯问题
    JS构造函数详解
    JS的prototype的共享机制分析
    使用a标签直接下载图片
  • 原文地址:https://www.cnblogs.com/chenxiaomeng/p/14579342.html
Copyright © 2020-2023  润新知