day15----总结 面向对象2

day15--总结 面向对象

  • 1.什么是内置属性

声明类的时候系统自动添加的属性(可能是字段也可能是对象属性)

class Person:
    """
    说明文档: 人类
    num - 人类的数量
    name - 人的名字
    """
    num = 61

    # 注意: 如果设置了__slots__的值,那么当前类的对象就不能使用__dict__属性
    # __slots__ = ('name', 'gender', 'age')

    def __init__(self, name, gender, age):
        self.name = name
        self.gender = gender
        self.age = age

    def eat(self,food):
        print('%s在吃%s' % (self.name, food))
        
#定制当前类的对象的打印
#1)重写__str__方法,这个方法的返回值就是对应的打印结果(类型必须是字符串)
def __str__(self):
    return '姓名:{},年龄:{},性别:{}'.format(self.name, self.age, self.gender)
    return '<'+str(self.__dict__)[1:-1]+'>'

#2)重写__repr__方法,这个方法的返回值就是对应的打印结果(类型必须是字符串)

def __repr__(self):
    return '<' + str(self.__dict__)[1:-1]+ '>'

p1 = Person('小明', '男',18)
  • 1.name

    类的字段;类名.name - 获取类的名字(是个字符串)
print(Person.__name__)    # Person
  • 2.doc

类的字段;类名.__doc__    -  获取类的说明文档
print(Person.__doc__)    # 
  • 3.class

对象属性;对象.__class__   -  获取对象的类 (和 type(对象)  的功能一样)
print(p1.__class__)   # 
print(type(p1))    # 
  • 4.dict - 将对象转换成字典

对象属性;对象.__dict__   --  将对象中所有的属性以属性和对应的值转换换成一个字典中的键值对(一个对象一个字典)
类的字段;类.__dict__ -  将类转换成一个字典,字典中的元素是类中所有的字段和对应的值
注意:如果设置了__slots__的值,当前类的对象就不能使用__dict__属性

print(p1.__dict__)    - #  {'name': '小明', 'gender': '男', 'age': 18}
  • 5.module

类的字段;类.__module__  - 获取当前类是在哪个模块中声明的,返回值是一个模块名称
print(Person.__module__)  # __main__

  • 6.bases

类的字段;类.__bases__  -   获取当前类的父类(返回的是一个元组)

print(Person.__bases__)    # (,)

私有化

  • 1.访问权限:公开,保护,私有
公开:公开的属性和方法在类的内部,外部都能用,可以被继承
保护:保护的属性和方法在类的类部内用,外部不能用,能被继承
私有:私有的属性和方法在类的内部和外部都不能用,不能被继承
  • 2.python中属性和方法的访问权限
python中所有的属性和方法都是公开的

怎么私有化:在需要私有化的属性或者方法名前加'__'(注意不能以'__'结尾)
python中私有化原理:在私有化的属性和方法前加'_类名'

属性的getter 和setter

在我们需要在获取属性值之前做点别的事情,就需要给这个属性添加getter

当需要给属性赋值之前做别的事情,需要给这个属性添加setter
  • 1.给属性添加getter
1)属性命名的时候前面添加'_'
2)在@property装饰器的后面声明一个对象方法
    a.将属性去掉下划线作为方法名
    b.方法除了self以外不需要其他参数
    c.函数的返回值就是获取这个属性的时候得到的值
3)在外部使用属性的时候,通过'对象.属性(不带下划线)'去使用
注意:获取属性值得时候,就会自动调用getter对应的方法
  • 2.属性添加setter
属性添加setter之前先添加getter(一般两个一起用)
1)属性名前加'_'
2)在@getter名.setter后面声明对象
    a.将属性下划线去掉作为方法名
    b.需要一个self以外的参数
    c.不需要返回值
3)在外部使用属性的时候,通过'对象.不带下滑线的属性'去使用

注意:当给属性赋值的时候,实质上是调用setter对应的方法
  • 练习:写一个矩形类
  • 有属性:长,宽,面积,周长
  • 要求从生活的角度去看这个矩形
class Rectangle:
    def __init__(self, long, width):
        self._long = long
        self._width = width
        self._area = 0
        self._perimeter = 0

    @property
    def long(self):
        return self._long

    @long.setter
    def long(self, value):
        if not(isinstance(value, int) or isinstance(value, float)):
            raise ValueError

        if value < 0:
            raise ValueError
        self._long = value


    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, value):
        if not(isinstance(value, int) or isinstance(value, float)):
            raise ValueError
        if value < 0:
            raise ValueError
        self._width = value

    @property
    def area(self):
        self._area = self._width * self._long
        return self._area

    @area.setter
    def area(self, value):
        return ValueError

    @property
    def perimeter(self):
        self._perimeter = 2 * (self._width + self._long)
        return self._perimeter

    @perimeter.setter
    def perimeter(self, value):
        return ValueError


r1 = Rectangle(100, 300)
print(r1.perimeter)
print(r1.area)
r1.width = 200
print(r1.width, r1.perimeter, r1.area)
# r1.long = 'nnn'
print(r1.long)

类方法和静态方法

  • 1.类中的方法
1)对象方法:(对象能做的的事,self都能做)
a.怎么申明:直接声明
b.怎么调用:用对象调用  '对象.对象方法()'
c.特点:有指向当前对象的self
d.什么时候用:如果实现函数的功能需要用到对象属性,就要选对象方法


2)类方法:(类能做的事 ,cls都能做)
a.怎么声明:声明在@classmathod后面
b.怎么调用:用类来调用   '类.类方法()'
c.特点:有自带参数cls,表示当前类;这个参数在调用的时候不用传参,系统自动将当前类传给他;
cls:谁调用就指向谁(如果是对象就指向对象对应的类)
d.什么时候用:实现函数的功能不需要对象属性但需要类的字段,就要用类方法


3)静态方法:
a.怎么声明:声明在@staticmethod后面
b.怎么调用:通过类来调用   '类.静态方法()'
c.特点:没有默认参数
d.什么时候用:实现函数的功能对象和类都不需要,就要静态方法

继承

  • 1.什么是继承
继承就是让子类直接拥有父类的属性和方法
子类   -  继承者
父类  -   被继承着
  • 2.怎么继承
1)语法:
class 类名(父类1, 父类2,...):
    说明文档
    类的内容

2)说明:
()   -  固定写法,如果省略相当于(object)
        声明类的时候如果没有写父类,默认继承object(object又叫基类)

父类   -   一个类的父类可以多个

在子类中可以通过supper()去调用分类的方法(只能在对象方法和类方法中使用)
在子类添加对象属性,先通过supper()调用父类的__init__来继承父类的对象属性
class Person:
    num = 61

    def __init__(self):
        print('Person中init')
        self.name = '小明'
        self.age = 18
        self.gender = '男'
        self.__a = 10

    def eat(self, food='米饭'):
        print('{}在吃{}'.format(self.name, food))

    @classmethod
    def show(cls):
        print('人类的数量:%d' % cls.num)

    @staticmethod
    def func1():
        print('人类')

    def func2(self):
        print('我是'+self.name)


class Student(Person):
    num = 10

    def __init__(self):
        # 在子类中添加对象属性,需要先通过super()去调用父类的__init__来继承父类的对象属性
        super().__init__()
        print('Student中init')
        self.study_id = '001'
        self.class1 = 'py1904'

    # 添加功能
    def study(self):
        print(self.name+'在好好学习!')

    @staticmethod
    def func1():
        print('学生')

    def func2(self):
        print('我是学生!')
        # 在子类中可以通过super()可以去调用父类的方法
        # 注意: super()只能在对象方法和类方法中使用
        super().func2()


stu1 = Student()
print(Student.num)    # 10
print('===================')
print(stu1.name, stu1.age, stu1.gender)  # 小明 18 男
print('===================')
stu1.eat()                    # 小明在吃米饭
print('===================')
Student.show()               # 人类的数量:10
print('===================')
print(stu1.__dict__)     # {'name': '小明', 'age': 18, 'gender': '男', '_Person__a': 10, 'study_id': '001', 'class1': 'py1904'}
print('===================')
Student.func1()          # 学生
print('===================')
stu1.func2()           # 我是学生!
                        # 我是小明
                        
                        

你可能感兴趣的:(day15----总结 面向对象2)