原创:叫我詹躲躲
来源:简书
链接:python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)
致谢:感谢求知教育提供的视频教程
1.单继承
## 封装,继承和多态 ## 1.封装 1、满足把内容封装到某个地方,另一个地方去调用封装的内容 2、使用初始化构造方法,或者使用self获取封装的内容 ## 2.继承 子类继承父类的属性和内容
1.1单继承示例
class Animal: def eat(self): print('吃饭了') pass def drink(self): print('喝水了') pass class Dog(Animal): def wwj(self): ## 子类独有的实现 print('小狗汪汪叫') pass class Cat(Animal): def mmj(self): ## 子类独有的实现 print('小猫喵喵叫') pass d1 = Dog() d1.eat() d2 = Cat() d2.eat() ## 总结:所以对于面向对象的继承来说,可以极大的提升效率,减少重复代码
2.多继承
class Shenxian: def fly(self): print('神仙会飞') pass class Monkey: def chitao(self): print('猴子喜欢吃桃') pass class Sunwukong(Shenxian,Monkey): pass swk = Sunwukong() swk.fly() swk.chitao()
2.1 注意方法重名:
## 多个父类存在相同的方法,该调用哪一个 class D(object): def eat(self): print('D.eat') pass class C(object): def eat(self): print('C.eat') pass class B(D): pass class A(B,C): pass a = A() a.eat print(A.__mro__) ##显示类的继承顺序 <class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class 'object'> ## 执行顺序应该是 去A里面查找,找第一个父类,A中没有的话,去B中查找,,B类中没有,C类中没有,去D类中查找;
2.2案例 简洁继承
class Grandfather(): def eat(self): print('吃的方法') pass pass class Father(Grandfather): pass class Son(Father): pass son = Son() print(Son.__mro__) ## <class '__main__.Son'>, ## <class '__main__.Father'>, ## <class '__main__.Grandfather'>, ## <class 'object'>
2.3重写父类方法
class Grandfather(): def eat(self): print('吃的方法') pass pass class Father(Grandfather): ## 覆盖了父类的方法 def eat(self): print('爸爸经常吃海鲜') pass class Son(Father): pass son = Son() print(Son.__mro__) ## 定义跟父类相同的方法,可以实现覆盖和重写父类的方法
2.4重写初始化方法
class Grandfather(): def __init__(self,name): self.name = name pass def eat(self): print('吃的方法') pass pass class Father(Grandfather): def __init__(self): pass ## 覆盖了父类的方法 def eat(self): print('爸爸经常吃海鲜') pass class Son(Father): pass son = Son() print(Son.__mro__)
2.5调用父类初始化方法
class Father: def __init__(self,name): self.name = name pass ## 覆盖了父类的方法 def eat(self): print('爸爸经常吃海鲜') pass class Son(Father): def __init__(self,name): Father.__init__(self,name) ##调用父类的方法,可以具备name属性 ## 或者 ## super.__init__(name) ##也可以这样写 self.age = 90 ## 添加新的实例方法 self.sex = '男' pass pass son = Son('hello')
2.6 调用父类的方法
class Father: def __init__(self,name): self.name = name pass ## 覆盖了父类的方法 def eat(self): print('父类的吃方法') pass class Son(Father): def __init__(self,name): Father.__init__(self,name) ##调用父类的方法,可以具备name属性 ## 或者 ## super.__init__(name) ##也可以这样写 self.age = 90 ## 添加新的实例方法 self.sex = '男' pass pass def __str__(self): print('{}'.format(self.name)) pass def eat(self): super().eat() ##调用父类的方法 print('子类的吃方法') pass son = Son('詹躲躲') son.eat() ## 父类的吃方法 ## 子类的吃方法
3 多态
同一种行为,对于不同子类【对象】有不同的实现方式
3.1 要想实现多态,必须有两个前提
1.继承:发生在父类和子类之间
2.重写:子类重写父类的方法
3.案例演示
class Animal: ## 基本类 def say(self): print('动物类') pass pass class Duck(Animal): ## 子类 派生类 def say(self): print('鸭子类') pass pass class Dog(Animal): ## 子类 派生类 def say(self): print('小狗类') pass pass ## duck1 = Duck() ## duck1.say() ## dog = Dog() ## dog.say() def commonIvoke(obj): ## 统一调用 obj.say() ## 循环统一调用 listObj = [Duck(),Dog()] for item in listObj: commonIvoke(item) ## 在定义时的类型跟调用时不一样的时候,称为多态。
3.2 多态的好处
1.增加程序的灵活性
2.增加程序的扩展性
4.类属性和实例属性
## 类属性:就是类对象拥有的属性,它被所有类对象的实例对象所共有,类对象和实例对象可以访问。 ## 实例属性:实例对象所拥有的属性,只能通过实例对象访问。 class Student: ## 类属性 name = '叫我詹躲躲' def __init__(self,age): self.age = age pass pass lm = Student(18) ## 通过实例对象去访问类属性 print(lm.name) print(lm.age) ## 通过类对象去访问 print(Student.name) print(Student.age) ## 总结 ## 类属性:类对象和实例对象都可以访问 ## 实例属性:只能由实例属性访问 ## 所有的实例对象指向同一类对象 ## 实例对象去修改类属性 不能修改 ## 类对象可以修改类属性 可以修改
5.类属性和静态方法
## 装饰器@classmethod class Person: country = 'china' ## 类方法 用classmethod修饰 @classmethod def get_country(cls): return cls.country ## 访问类属性 pass @classmethod def change_country(cls): cls.country = 'America' pass ## 通过类对象去引用 print(Person.get_country()) print(Person.change_country()) print(Person.get_country())
5.1 静态方法
class Person: country = 'china' ## 类方法 用classmethod修饰 @classmethod def get_country(cls): return cls.country ## 访问类属性 pass @classmethod def change_country(cls): cls.country = 'America' pass @staticmethod def get_data(): return Person.country pass ## 通过类对象去引用 print(Person.get_country()) print(Person.change_country()) print(Person.get_country()) print(Person.get_data())
一般不会通过是实例对象去访问静态方法
由于静态方法主要存放逻辑方法,本身与类以及实例没有交互,也就是不会涉及类中方法和属性的操作
根据资源能够有效的利用
5.2求系统当前的时间
import time class sys_time: def __init__(self,hour,min,second): self.hour = hour self.min =min self.second = second @staticmethod ## 独立的功能 def show_time(): return time.strftime('%H:%M:%S',time.localtime()) print(sys_time.show_time()) ## 15:15:44
5.3 总结
1.类方法的第一个参数是类对象,cls进而去引用类对象的属性和方法
2.实例方法的第一个参数是实例属性,若存在相同的实例属性或者方法,实例属性优先级最高
3.静态方法不需要额外的参数,若需要引用属性。,则可以通过类对象或者实例对象去引用即可,必须使用装饰器@staticmethod装饰
6.私有化
6.1 私有化属性
## 私有属性 以__开头,声明为属性私有,不能在类的外部被使用或者直接访问。 class Person(object): def __init__(self): self.__name = '叫我詹躲躲' ## 私有化 self.age = '21' pass def __str__(self): return '{}的年龄是{}'.format(self.__name,self.age) person = Person() ## print(person.__name) ##报错 print(person) ##可以访问 ## 叫我詹躲躲的年龄是21 ## 私有属性,不能被子类继承
6.2私有化方法
class A(object): def __eat(self): print('吃饭') pass pass def run(self): print('跑步') pass pass b = A() b.__eat() ## 报错 b.run() ## 跑步
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(下):https://developer.aliyun.com/article/1483380