第020篇:面向对象2
严格来说,python类中的内容只有公开的;私有化是假的私有化。
公开的(public):类的里面、类的外面都可以用,也就可以被继承
保护的(protect):类的里面可以使用,类的外面不能使用,也可以被继承
私有的(private):只有类的里面可以用,类的外面不能用,也不能被继承
在方法名前或者属性名前加两个下划线(__),但是名字后面不能加(__)
原理:并不是真的私有化,而是在两个下划线(__)开头前的属性名和方法名前加了 '_类名'
class Person: num = 61 __num2 = 66 def __init__(self, name, age=18): self.name = name self.age = age self.__gender = '男' def func1(self): print('%s今年%d岁' % (self.name, self.age)) print('--->', Person.__num2, self.__gender) @staticmethod def func2(): print('我是静态方法') @staticmethod def __func21(): print('我是静态方法') print('=====默认的方法在外面都可以用=====') print(Person.num) p1 = Person('小白') print(p1.name, p1.age) p1.func1() Person.func2() print('=====私有的属性和方法=====') # print(p1.__num2) # print(p1.__gender) # p1.__func21() # print(p1._Person__gender) # print(p1.__dict__)代码演示
如果希望在给对象属性赋值前做点别的事情就给这个属性添加setter
如果希望在获取属性值之前做点别的什么事情就给这个属性添加getter
注意:如果想要给属性添加setter必须先添加getter
getter:
a、将需要添加的getter的属性名前加下划线(_)
b、声明函数:
声明前加@property
函数名不带_的属性名
函数需要一个返回值,返回值就是获取这个属性能够得到的值
c、在外面使用属性的时候不带下划线
setter:
a、声明函数:
声明前加 @getter名.setter;
函数名不带下划线(_)的属性名
函数不需要返回值,但是需要一个参数,这个参数就是给属性赋的值
b、在外面给属性赋值的时候不带下划线
class Person: def __init__(self): self._age = 10 self._time = 1574749694.0996032 @property def time(self): t_time = time.localtime(self._time) return '{}-{}-{}'.format(t_time.tm_year, t_time.tm_mon, t_time.tm_mday, ) @property def age(self): return self._age @age.setter def age(self, value): print('value:', value) if isinstance(value, int): if 0 <= value <= 200: self._age = value else: raise ValueError else: raise ValueError p1 = Person() p1.age = 18 # p1.age = 'abc' # p1.age = [12, 32, 12] print(p1.time) class Circle: pi = 3.1415926 def __init__(self, r): self.r = r self._area = 0 @property def area(self): return Circle.pi * self.r ** 2 @area.setter def area(self, value): print('赋值:', value) c = Circle(1) print(c.area) # 本质是在调用area函数:c1.area() c = Circle(4) print(c.area) c.r = 10 print(c.area) c.area = 2 # # 本质是在调用setter的area函数:c1.area()getter和setter代码演示
继承是让子类直接用于父类的属性和方法
子类 - 继承者(儿子)
父类 - 被继承者(老子),又叫超类
语法: class 类名(父类1, 父类2, ...): 类的说明文档 内容
父类所有的属性和方法都可以继承
class Person: num = 66 def __init__(self): self.name = '小明' self.age = 18 @staticmethod def func1(): print('静态方法') class Student(Person): def func2(self): print(self.name) # 子类直接使用父类的属性和方法 Student().func2() Student().func1() print(Student.num)子类直接使用父类的属性和方法
1)添加方法和字段: 在子类中直接声明新的字段和方法 注意:如果添加的字段名和方法名和父类的字段方法同名了,子类中的字段和方法会覆盖父类的字段和方法 -> 重写 2)添加对象方法 在自己的init方法中添加新的属性,并且需要通过supper()去调用父类的__init__方法继承父类的对象属性
可以在类中的任何一个对象方法或者类方法去通过supper()调用父类的对象方法或者类方法;不能调用静态方法。 super(类1,类1的对象).方法() --> 调用类1中父类的方法 super().方法() <==> super(当前类, 当前类的对象) super(type, obj) --> obj必须是type的对象或者是type的子类对象
class Animal: num = 100 def __init__(self): self.age = 10 self.gender = '母' @staticmethod def a_func(): print('Animal的方法1') def a_func1(self): print('动物中的对象方法') class Cat(Animal): voice = '喵~' def __init__(self): super().__init__() # 调用当前类的父类的方法 self.color = '灰色' self.breed = '田园猫' @staticmethod def c_func1(): print('猫中的静态方法') # 静态方法中不能使用supper() # super().a_func() def c_func2(self): super().a_func1() print(Cat.num, Cat.voice) Cat().a_func() Cat().c_func1() cat1 = Cat() print(cat1.age, cat1.gender) cat1.c_func2()代码演示1
class A: def func(self): print('this is A') class B(A): def func(self): print('this is B') class D(A): def func(self): print('this is D') class C(B): def func(self): # super().func() # super(C, self).func() # super(B, self).func() # super(D, D()).func() # super(A, A()).func() print('this is C') obj = C() # ==> super().func() # obj.func() # this is B; this is C # ==> super(C, self).func() # obj.func() # this is B; this is C # ==> super(B, B()).func() / super(B, self).func() # obj.func() # this is A; this is C # ==> super(D, D()).func() # obj.func() # this is A; this is C # ==> super(A, A()).func() # obj.func() # AttributeError: 'super' object has no attribute 'func'代码演示2
查看继承顺序: 先画出和需要的类相关联的所有的父类的继承关系,然后从左往右看没有子类的类
print(D.__mro__) 用于查看继承顺序
class Animal: num = 100 def __init__(self, age=0, gender='雄'): self.age = age self.gender = gender def a_func1(self): print('动物的对象方法') def message(self): print('this is Animal') class Fly: flag = '飞行' def __init__(self, height=1000, time=3): self.height = height self.time = time @classmethod def f_func1(cls): print('飞行的类方法') def message(self): print('this is Fly') class Bird(Animal, Fly): pass class A1: def message(self): super(Bird, Bird()).message() b1 = Bird() # 字段都可以继承 print(Bird.num, Bird.flag) # 方法都可以继承 b1.a_func1() Bird.f_func1() # 对象属性只能继承第一个父类的 print(b1.age, b1.gender) # print(b1.height, b1.time) # AttributeError: 'Bird' object has no attribute 'height' b1.message() A1().message()代码演示1
class A: def message(self): print('this is A') class B(A): def message(self): super().message() print('this is B') class C(A): def message(self): super().message() print('this is C') class D(B, C): def message(self): super().message() print('this is D') class E(C): def message(self): super().message() print('this is E') class F(D, E): def message(self): super().message() print('this is F') class G(F): def message(self): super().message() print('this is G') D().message() """ 'this is A' 'this is B' 'this is D' """ print(D.__mro__)代码演示2
class A: def message(self): print('this is A') class B: def message(self): super().message() print('this is B') class C(B, A): def message(self): super().message() print('this is C') class D(B): def message(self): super().message() print('this is D') class E(C): def message(self): super().message() print('this is E') class F(D, E): def message(self): super().message() print('this is F') class K(F): def message(self): super().message() print('this is K') F().message() print(F.__mro__)代码演示3
优质内容筛选与推荐>>