python新手入门笔记(八)—— 面向对象
python新手入门笔记(八)—— 面向对象
概念
面向过程:根据业务逻辑从上到下写垒代码
函数式:将某功能代码封装到函数中,日后便无须重复编写,仅调用函数即可。
面向对象:将数据与函数绑定到一起,进行封装,这样能更快地开发程序,减少重复代码的重写过程。
注:以上论述非定义,仅描述概念作用。
类和对象的概念及定义
类就是一个模板,可包含多个函数,函数里实现功能。相当于图纸。
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数。相当于根据图纸生产出的具体物品。
object:基类,其他所有类的
class Person: name = 'xiaoming' age = 18 def eat(self): print('吃饭') xiaoming = Person() print(xiaoming.age) xiaoming.eat()
实例方法和属性
属性:类中定义的变量
方法:类中定义的函数
方法有三种:实例方法、类方法、静态方法
简单来说,函数def xxx(self): 带有self的都是实例方法。
class Person: height = 1.8 # 类属性 def __init__(self): # 初始化方法,当对象被创建完成的时候,这个方法会第一个执行,且自动执行 self.name = '小埋' # 实例属性 # 实例方法 def text(self): print('实例方法') xm = Person() print(xm.height) print(xm.name) xm.text() class Person: # __init__,对象初始化方法 def __init__(self,name,age):# self指的就是下方xm对象,即对象本身 # 初始化方法,当对象被创建完成的时候,这个方法会第一个执行,且自动执行 self.name = name # 实例属性 self.age = age # 实例方法 def text(self): print('实例方法') xm = Person('小埋',18) # xm是对象,可随意命名,可创建多个对象 print(xm.name) print(xm.age)
实例方法里的self实际就是我们创建的对象xm。
class Car: def get_self(self): print(f'self的id是{id(self)}') bmw = Car() print(id(bmw)) # 2447193969664 bmw.get_self() # self的id是2447193969664 ree = Car() print(id(ree)) # 2871479535312 ree.get_self() # self的id是2871479535312
两者id指向同一个内存空间地址,说明两者是同一个。创建不同对象,id也不同,self的id也只跟随不同的对象发生改变。上例中实际是做出了
xxx = Car(xxx)的处理(Car(xxx) == Car(self))。
面向对象三大特性:封装、继承、多态
封装
1、封装是面向对象编程的一大特点。
2、把属性和方法封装到一个抽象类中。
3、外界使用类创建具体的对象,让对象调用具体的方法。
4、对象方法的细节都被封装在类的内部。
import random class Hero: def __init__(self,name,konfu): self.name = name self.blood = 100 self.kongfu = konfu def kill(self,enemy): '''出招攻击''' info = f'{self.name}一招{self.kongfu}攻向了{enemy.name}' print(info) rand = random.randint(20,40) enemy.blood -= rand print(f'{enemy.name}掉了{rand}滴血.') def yun(self): '''运功疗伤''' rand = random.randint(5,10) self.blood += rand info = f'{self.name}运功疗伤,加了{rand}滴血。' print(info) def __str__(self): # 模板方法 return f'{self.name}还剩{self.blood}滴血' if __name__ == '__main__': # 这段代码下的代码只会在当前文件页生效,常被用作测试使用,该代码无法被导入 guojing = Hero('郭靖','降龙十八掌') # 创建对象,即为对象分配内存空间,同时init方法为对象设置属性 wentian = Hero('南宫问天','天外飞仙') guojing.kill(wentian) wentian.yun() print(guojing) print(wentian)
继承
子类继承父类的属性方法,使子类不需要重复定义父类所拥有的的属性和方法即可调用。即实现代码重用,相同的代码不用重复编写。
class Animal: def __init__(self,name): self.name = name def eat(self): print(f'{self.name}吃东西') def drink(self): print('喝东西') class Dog(Animal): pass class Cat(Animal): def miao(self): print('喵喵喵') if __name__ == '__main__': wangcai = Dog('旺财') wangcai.eat() Tom = Cat('Tom') Tom.miao()
多继承
一个子类继承多个父类的属性和方法。
class A: def eat(self): print('吃东西a') class B: def drink(self): print('喝东西') def eat(self): print('吃东西b') class C(A,B): pass if __name__ == '__main__': c = C() c.eat() c.drink()
还有个钻石继承,以后了解。
重写
重写父类方法,分为两种情况:
1、覆盖父类方法
如果子类和父类拥有同名方法,子类方法会覆盖掉父类方法。
2、对父类方法的拓展
父类方法是子类方法的一部分。
在需要调用父类方法时,在子类方法中使用super().父类方法来调用父类方法。
对于第一种情况,如下:
class Base1: def test(self): print('-------base1--------') class Base2: def test(self): print('-------base2--------') class A(Base1): def test(self): print('---------A----------') class B(Base2): def test(self): print('---------B----------') class C(A,B): def test(self): print('---------c----------') if __name__ == '__main__': c = C() c.test() # ---------c---------- print(C.__mro__) # 继承的搜索路径
所有的类中都有test方法,但执行结果只有一个,且结果说明两点:
- 方法就近原则:对象执行方法由最近的类开始寻找,有就执行当前方法,无就继续寻找。
- 覆盖父类:即重写,子类虽然继承了父类的方法,但子类本身拥有同名方法,子类方法会覆盖掉父类方法。
对于第二种情况,有三种写法:
1、父类名.方法名(self,属性名…)
2、super(子类名,self).方法名()
3、super().方法名()
其中第三种是最常用的方法,因为简单。
注:super是一个类。
如下:
class Man: def game(self): print('玩耍') class SuperMan(Man): def game(self): Man.game(self) # 调用父类方法 super(SuperMan,self).game() # 调用父类方法 super().game() # 调用父类方法,最常用的方法 print('飞着玩') if __name__ == '__main__': Clarkent = SuperMan() Clarkent.game()
多态
多态是由封装和继承引起的一种现象,没有具体的写法。
指同一种事物的多种形态。
不同的对象调用相同的方法,产生不同的执行结果,增加代码灵活度
class Cat: def __init__(self,name): self.name = name def game(self): print(f'{self.name}愉快地玩耍') class CatYao(Cat): def game(self): print(f'{self.name}愉快地在天上玩耍') class Person: def __init__(self,name): self.name = name def game_with_cat(self,cat): print(f'{self.name}和{cat.name}愉快地玩耍') cat.game() if __name__ == '__main__': # tom = Cat('tom') tom = CatYao('tom') xiaoming = Person('小埋') xiaoming.game_with_cat(tom) # 调用game方法时只需改变类即可改变game方法,即上面tom对象的调用
多态并无新的语法,只是调用的技巧而已,根据传入对象的不同,实现的方法也不同。
class A: def show(self): print('Ashow') class B(A): def show(self): super().show() print('Bshow') class C: def show(self): print('Cshow') class D(C): def show(self): super().show() print('Dshow') # return 0 def obj(obj): obj.show() # print(obj.show()) if __name__ == '__main__': test1 = B() test2 = D() obj(test1) obj(test2)
注:在obj函数中,如果我们用的是print,那么它打印出来的不仅仅是各类中show()函数中的执行方法,还有其返回值,而各类中并无return,即D类中的
retrun 0,它默认返回一个None值,则执行结果除了执行各类中的语句外,还返回了一个None值。如果不想有None值的返回,则直接调用方法即可,即
obj.show()。
总结
- 创建出来的对象叫做类的实例
- 创建对象的动作叫做实例化
- 对象的属性叫做实例属性
- 对象调用的方法叫做实例方法
- 对象各自拥有自己的实例属性
- 调用对象方法,可以通过self访问自己的属性,以及调用自己的方法
def x(): self.xx() def xx(): pass
- python 中一切皆为对象,比如类也是对象
- 类对象也有自己的属性和方法
class Person: country = 'China' # 类属性 def __init__(self,name): # 实例方法 self.name = name #实例属性 if __name__ == '__main__': xm = Person('小埋') print(xm.country) # 通过实例对象访问类属性 print(Person.country) # 通过类本身访问类属性 print(xm.name) # 通过对象访问实例属性 # print(Person.name) # type object 'Person' has no attribute 'name',类对象不能访问实例属性 xm.country = 'USA' # 通过实例对象修改类属性 print(xm.country) # 实例属性修改了 print(Person.country) # 类属性没有被修改 Person.country = 'UK' # 通过类修改类属性 print(Person.country) # 类属性被修改了 print(xm.country) # 如果是类属性修改前创建的修仙,属性不会被修改 xx = Person('HAHAHA') print(xx.country)
- Python学习笔记(四):面向对象、正则表达式(快速入门篇)
- python3.5入门笔记(二)---------------面向对象
- Python面向对象高级编程——学习笔记
- [Python学习笔记][第六章Python面向对象程序设计]
- 学习笔记(01):600 分钟搞定 Python 入门到实战-内置对象类型-ed
- 【Python 笔记(2)】Python面向对象
- 学习笔记(03):Python零基础轻松从入门到实战-内置对象类型-ed
- 学习笔记(01):600 分钟搞定 Python 入门到实战-内置对象类型-ed
- Python笔记(4):面向对象,迭代器,生产器
- 笔记:python基础之面向对象特性——继承
- 9.Python笔记之面向对象高级部分
- python入门之面向对象
- Python新手入门英文词汇笔记
- 学习笔记(02):5天Python闯关训练营-105期-Python面向对象
- python 面向对象入门 - 之 单元测试
- C++入门学习笔记(一)--面向对象基本概念
- < 笔记 > Python - 08 Python 面向对象高级编程(OOP Advanced Features)
- Python3入门(基础语法,基本数据类型,条件控制,循环语句,函数,文件,面向对象,作用域)
- Python笔记day22(对象)|初识面向对象
- 【Python】学习笔记——-8.3、面向对象高级编程:3.多重继承