美文网首页
day15-类和对象2

day15-类和对象2

作者: 冯书简 | 来源:发表于2019-06-21 16:53 被阅读0次

    类方法和静态方法

    1.类中的方法

    1)对象方法
    a.怎么声明: 直接声明在类中的函数
    b.怎么调用: 通过对象来调用
    c.特点: 有个指向当前对象的默认参数self;调用的时候不需要传参
    d.什么时候用: 实现函数的功能需要用到对象属性

    2)类方法
    a.怎么声明: 声明函数前加'@classmethod'
    b.怎么调用: 通过类来调用, '类.方法名()'
    c.特点: 有个默认参数cls, 这个参数在通过类调用的时候不需要传参; 指向当前类(谁调用指向谁)
    类能做的事情,cls都可以做
    d.什么时候用: 实现函数的功能不需要对象属性的前提下,需要类的字段(需要类),这个时候就用类方法

    3)静态方法
    a.怎么声明: 声明函数前加'@staticmethod'
    b.怎么调用: 通过类来调用, '类.方法名()'
    c.特点: 没有特点(没有默认参数)
    d.什么时候用:实现函数的功能既不需要对象属性也不需要类的字段,这个时候就使用静态方法

    class Student:
        # 字段
        num = 30
    
        # 对象属性
        def __init__(self, name, tel, age=18):
            self.name = name
            self.age = age
            self.tel = tel
            self.study_id = '001'
    
        # 对象方法
        def study(self):
            print('%s在学生' % self.name)
            print(Student.num)
    
        # 类方法
        @classmethod
        def count(cls):
            print('=========类方法中===========')
            print('cls:', cls)
            stu = cls('小花', '12832')
            print(stu, cls.num)
            cls.func()
            print('类方法1')
    
        @classmethod
        def func(cls):
            print('类方法2')
    
        # 静态方法
        @staticmethod
        def static_func():
            print('静态方法!')
    
    
    stu1 = Student('小明', '001292')
    # 对象方法通过对象调用
    stu1.study()
    
    # 类方法通过类调用
    print('Student:', Student)
    Student.count()
    
    # 类调用静态方法
    Student.static_func()
    
    
    class Human:
        num = 61
    
        @staticmethod
        def func1():
            print(Human.num)
    
    
        @classmethod
        def func2(cls):
            print(cls.num)
    
    
    class Student(Human):
        num = 40
        pass
    
    
    Student.func1()
    Student.func2()
    Human.func2()
    

    私有化

    1.访问权限

    公开(public): 属性和方法在类的内部可以使用、可以被继承也可以在类的外部使用
    保护(protect): 属性和方法在类的内部可以使用、可以被继承;不能在类的外部使用
    私有(private): 属性和方法在类的内部可以使用、不可以被继承,也不能在类的外部使用

    python中本质上所有的属性和方法都是公开的,私有化是假的私有化

    2.私有化

    语法: 在声明属性或者方法的时候,在属性名前或者方法名前加'';
    注意: 只能'
    '开头,不能以'__'结尾

    私有化的原理: 只是单纯在私有属性或者方法名前加'_类名', 导致直接使用原名使用不了属性和方法

    class Person:
        num = 61
        __num1 = 100
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.__gender = gender
    
        def eat(self, food: str):
            print('%s在吃%s' % (self.name, food))
            print('性别: ', self.__gender)
    
        @classmethod
        def show_num(cls):
            print('人类的数量:%d' % cls.num, cls.__num1)
    
        def __run(self):
            print('%s在跑' % self.name)
    
    
    p1 = Person('小明', 18, '男')
    print(Person.num)
    p1.eat('面包')
    Person.show_num()
    
    # print(Person.__num1)   # AttributeError: type object 'Person' has no attribute '__num1'
    # print(p1.__gender)   # AttributeError: 'Person' object has no attribute '__gender'
    # p1.__run()     # AttributeError: 'Person' object has no attribute '__run'
    print(p1._Person__gender)
    
    print(p1.__dict__)
    
    class Student(Person):
        @classmethod
        def func1(cls):
            print(cls.__num)
    
    
    print('学生:', Student.num)
    # Student.func1()
    # print('学生:', Student.__num)
    

    getter和setter

    3 1.什么时候使用getter和setter

    1)getter - 希望获取一个属性值之前做别的事情,就给这个属性添加getter
    2)setter - 希望给属性赋值之前做点儿别的事情,就给这个属性添加setter

    2.怎么给属性添加getter和setter

    1)怎么添加getter:
    a. 在需要添加getter的属性前加_
    b. 在@property后面声明一个函数;函数名和去掉的属性名一致, 并且函数需要一个返回值表示获取属性的值
    c. 在外面通过不带
    的属性名去获取对应的属性值

    2)怎么添加setter:
    a. 如果想要给属性添加setter必须先给它添加getter
    b. @getter名.setter后声明函数;函数名和去掉的属性名一致, 这个函数不需要返回值,但是需要一个参数
    c.在外面通过不带
    的属性名去给属性赋值

    class ReadError(Exception):
        def __str__(self):
            return '给只读属性赋值!'
    
    
    class Rect:
        def __init__(self, width, length):
            self.width = width
            self.length = length
            self._area = 0
            self._perimeter = 0
            self._gender = 1
            self._age = 0
    
        # ============添加getter============
        @property
        def area(self):
            return self.width * self.length
    
        @property
        def gender(self):
            if self._gender == 1:
                return '男'
            else:
                return '女'
    
        @property
        def age(self):
            return self._age
    
        # ================setter================
        @age.setter
        def age(self, value):
            if type(value) != int:
                print('数据有误!数据类型不是整型')
                raise ValueError
    
            if 0 < value <= 200:
                self._age = value
            else:
                print('数据有误!年龄值超过了正常范围!')
                raise ValueError
    
        @area.setter
        def area(self, value):
            # print('area属性是只读的!')
            raise ReadError
    
    
    r1 = Rect(4, 6)
    print(r1.area)
    r1.width = 10
    print(r1.area)
    print(r1.gender)
    print(r1.gender)
    print(r1.gender)
    
    # r1.age = 'abc'
    # r1.age = 1000
    r1.age = 26      # r1.age(26)
    print(r1.age)    # r1.age()
    
    # r1.area = 100
    

    继承

    1.什么是继承

    让子类直接拥有父类的属性和方法,这个过程就是继承。

    2.怎么继承

    python中所有的类,默认都是继承自object。(object是基类)

    1)语法:
    class 类名(父类1,父类2,..):
    类的内容

    继承发生后子类直接拥有父类的所有的属性和方法

    3.子类添加内容

    1. 添加字段和方法
      直接在子类中声明新的字段或者方法
    2. 添加对象属性

    补充:
    1)类中的函数的调用: 先看当前类中有没有这个方法,如果有直接调用;如果没有就看父类有没有这个方法,有的话就调用;
    如果没有就看父类的父类有没有这个方法...
    以此类推,如果找到基类都没有,程序才会报错

    2)super()的使用
    在子类的对象方法和类方法中都可以通过super()去调用父类的对象方法和类方法;
    在子类中的静态方法中不能使用super()

    class Person:
        num = 61
    
        # 注意: __slots__只能约束当前类的对象,不能约束它的子类对象
        __slots__ = ('name', 'age', 'gender')
    
        def __init__(self, name='张三', age=0, gender='男'):
            print('创建对象!')
            self.name = name
            self.age = age
            self.gender = gender
    
        def eat(self, food: str):
            print('%s在吃%s' % (self.name, food))
    
        @staticmethod
        def func1():
            print('Person中的静态方法')
    
    
    class Student(Person):
    
        def __init__(self):
            # 在这儿去调用父类的__init__方法
            super().__init__()
            print('创建学生对象!')
            self.study_id = '001'
            self.score = 0
    
        pre = 'stu'
    
        @staticmethod
        def study():
            print('good good study, day day up!')
    
        @staticmethod
        def func1():
            print('Student中的静态方法')
            # super().func1()
    
    
    # 1.子类可以继承父类的属性和方法
    print(Student.num)
    stu = Student()
    print(stu.name, stu.age, stu.gender)
    stu.eat('火锅')
    
    # 2.__slots__不能约束子类
    # p1 = Person()
    # p1.id = '001'  # AttributeError: 'Person' object has no attribute 'id'
    # stu.id = '001'
    
    
    # 3.子类可以使用子类中的内容,但是父类不可以使用
    print(Student.pre)
    Student.study()
    # print(Person.pre)   # AttributeError: type object 'Person' has no attribute 'pre'
    
    
    print(stu.study_id)
    
    Student.func1()
    
    
    class Animal:
        def __init__(self, age, gender):
            self.age = age
            self.gender = gender
    
    
    class Cat(Animal):
        def __init__(self, type, color, age, gender):
            super().__init__(age, gender)
            self.type = type
            self.color = color
    
    
    cat1 = Cat('加菲猫', '黄色', 10, '公')
    print(cat1.__dict__)
    

    相关文章

      网友评论

          本文标题:day15-类和对象2

          本文链接:https://www.haomeiwen.com/subject/pdluqctx.html