前言:
面向对象(oop)是一种编程方法,编程思想,适用于中大型项目;
面向过程也是一种编程思想,适用于小型项目。
面向过程 和 面向对象 都可以实现某个编程目的,面向过程考虑的是 实现的细节;面向对象考虑的是 结果(谁能做这件事)。
面向对象
类class:是对具有相同特征或者行为的事物的统称,是抽象的,不能直接使用(指代多个事物)
对象:是由类创建出来的一个具体存在的事物,可以直接使用(指代一个具体事物)
类的构成
1、类名:标识符规则、见名知意、大驼峰(所有单词首字母大写)命名法
2、属性:事物的特征
3、方法:事物的行为
面向对象代码的步骤:
1、设计类(找类的三要素)
2、定义类
3、创建对象(实例化对象)
4、由对象调用类中的方法
面向对象基本语法:
# 定义类
class 类名:
def 方法名(self): # 方法的本质是函数
pass
# 创建对象(实例化对象)
变量 = 类名() # 一般将这个变量成为对象(本质:变量中保存的是对象的引用地址)
# 调用类中的方法
对象.方法名() # 对象就是上面那个变量
# 例子:小猫爱吃鱼,小猫要喝水
self参数
1、self是形参,名字可以任意,但习惯性上叫self
2、self是一个普通参数,调用函数的时候需要传递实参,而目前Python解释器自动将调用这个方法的对象作为参数传递给self(即:self就是调用这个方法的对象,上述例子,self就是mi)
类外面添加属性,只适用于该操作对象
类里面添加属性,需用到__init__ 方法
初始化对象,给对象添加属性,若属性值是变化的,则可以将这个属性的值作为参数传递,创建对象的时候传递实参;
创建对象的时候,__init__方法会自动调用
__str__方法:用于print(对象)时返回字符串
dir(对象) 返回对象内的所有属性和方法
面向对象案例
1 ''' 2 面向对象案例一: 3 小明体重75公斤 4 小明每次跑步会减肥0.5公斤 5 小明每次吃东西会增加1公斤 6 ''' 7 8 class Human: 9 def __init__(self, name, weight): 10 self.name = name 11 self.weight = weight 12 13 def __str__(self): 14 return f'{self.name}现在的体重是{self.weight}公斤' 15 16 def run(self): 17 self.weight -= 0.5 18 19 def eat(self): 20 self.weight += 1 21 22 if __name__ == '__main__': 23 xiaoming = Human('小明',75) 24 for i in range(10): # 跑了十次步 25 xiaoming.run() 26 for j in range(3): # 吃了三次东西 27 xiaoming.eat() 28 print(xiaoming)
1 ''' 2 面向对象案例二: 3 房子有户型、总面积、家具名称列表(新房子没有任何家具) 4 家具有名字、占地面积: 5 席梦思 占地 4 平米 6 衣柜 占地 2 平米 7 餐桌 占地 1.5平米 8 9 将以上三件家具添加到房子中 10 打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表 11 ''' 12 13 class Jj: 14 ''' 15 类名:Jj 16 属性:家具名name,占地面积area 17 方法:__str__() 返回XXX的占地面积是XXX 19 ''' 20 def __init__(self, name, area): 21 self.name = name 22 self.area = area 23 24 def __str__(self): 25 return f'{selef.name}的占地面积是{self.area}' 26 27 28 class House: 29 ''' 30 类名:House 31 属性:户型hx,总面积zmj,剩余面积rarea,家具列表jjs 32 方法:addJj() 往家具列表中添加家具名,并修改剩余面积 33 __str__() 返回房子的基本情况 34 ''' 35 36 def __init__(self, hx, zmj): 37 self.hx=hx 38 self.zmj = zmj 39 self.rarea = zmj 40 self.jjs = [] 41 42 def addJj(self, JjObject): 43 if self.rarea >= JjObject.area: 44 self.jjs.append(JjObject.name) 45 self.rarea -= JjObject.area 46 else: 47 print(f'剩余面积为{self.rarea},{JjObject.name}占地{JjObject.area},放不下') 48 def __str__(self): 49 return f'户型:{self.hx},总面积:{self.zmj},剩余面积:{self.rarea},家具名称列表:{self.jjs}' 50 51 if __name__ == '__main__': 52 xi = Jj('席梦思', 4) 53 gui = Jj('衣柜', 2) 54 zhuo = Jj('餐桌', 1.5) 55 56 chen = House('A型', 100) 57 chen.addJj(xi) 58 chen.addJj(gui) 59 chen.addJj(zhuo) 60 print(chen)
面向对象的三大特征:封装、继承、多态
继承
1、继承描述的是类与类之间的关系 is ... a
2、减少代码冗余,重复代码不需要多次书写,提交编程效率
3、继承具有传递性:子类可以继承父类的父类的属性和方法
4、对象使用属性/调用方法飞顺序:自己类->父类->父类的父类->...->object类,一直没有就报错
语法:
1 class A(object): # 默认继承object类,object类是Python中最原始的类 2 pass 3 4 class B(A): # 类B继承类A 5 pass 6 7 ''' 8 类A:父类 或 基类 9 类B:子类 或 派生类 10 子类继承父类之后,子类对象可以直接使用父类中的属性和方法 11 '''
案例:
class Animal: def __init__(self, name, age): self.name = name self.age = age def eat(self): print(f'{self.name}在吃东西') def sleep(self): print(f'{self.name}在睡觉') class Cat(Animal): def zhua(self): print(f'{self.name}在抓老鼠') class Dog(Animal): def kan(self): print(f'{self.name}在看门') class Xiaotianquan(Dog): def fly(self): print(f'{self.name}在飞') if __name__ == '__main__': peiqi = Animal('佩奇', 2) peiqi.eat() peiqi.sleep() tom = Cat('Tom', 4) tom.eat() tom.sleep() tom.zhua() wangcai = Dog('旺财', 5) wangcai.eat() wangcai.sleep() wangcai.kan() xiao1 = Xiaotianquan('哮1', 18) # 子类对象不管有没有用到父类的属性和方法,都需要在实例化对象的时候传父类的参数 xiao1.eat() xiao1.sleep() xiao1.kan() xiao1.fly()
重写(override):
当子类定义了与父类一样的方法,且父类中的代码不能满足子类对象的需要
分类:
1、覆盖式重写:直接在子类中定义与父类方法名一样的方法
2、扩展式重写:父类中的功能还需要,只是添加了新的功能
① 子类中定义与父类一样的方法名
② 子类中方法中,使用super().方法名() 调用父类中的功能
③ 书写新的功能
# 覆盖式重写 class Dog: def dark(self): print('汪汪叫....') class XTQ(Dog): def dark(self): super().dark() print('嗷嗷叫....') x = XTQ() x.dark()
汪汪叫....
嗷嗷叫....
多态
一种调用代码的技巧,不同的子类对象调用相同的方法,产生不同的执行结果(本质:对象调用方法,先去本身的类里面找方法,没有就再去父类找)
# 多态实例 class Dog: def game(self): print('普通狗在简单的玩耍') class XTQ(Dog): def game(self): print('哮天犬在天上玩耍') class Person: def p_d(self, dogObj): # dogObj可以是Dog类对象,也可以是Dog类的子类对象(XTQ类) print('人在和狗玩耍') dogObj.game() if __name__ == '__main__': Lily = Person() hei = Dog() xtq = XTQ() Lily.p_d(hei) Lily.p_d(xtq) # hei和xtq是不同的子类对象,它们调用了相同的方法game,产生了不同的执行结果
私有和公有
公有权限:
直接定义的属性和方法就是公有的,可以在任何地方访问和使用
私有权限:
只能在类内部定义(class关键字的里面),只需要在属性名和方法名前面加上__就变成私有的了
私有只能在当前类的内部使用,不能在类外部和子类直接使用
案例:
# 案例:私有属性__age只能在Person类中使用,外部无法使用和修改 class Person: def __init__(self, name, age): self.name = name self.__age = age # 定义一个私有的属性__age def __str__(self): return f'{self.name},{self.__age}' # 使用的是私有属性__age if __name__ == '__main__': tom = Person('汤姆', 10) print(tom.__age) # 报错,类外部无法使用私有属性__age print(tom) # 汤姆,10 tom.__age = 100 # 添加一个公有属性__age,无法修改私有属性__age print(tom.__age) # 打印刚添加的公有属性100 print(tom) # 汤姆,10 打印的还是私有属性10 print(dir(tom)) # 其中'_Person__age', '__age' 分别是私有属性和公有属性 # 案例:可以定义一个公有方法set_age,允许类外部修改私有属性__age class Person: def __init__(self, name, age): self.name = name self.__age = age # 定义一个私有的属性__age def __str__(self): return f'{self.name},{self.__age}' # 使用的是私有属性__age # 定义一个公有方法来修改私有属性__age def set_age(self, new_age): self.__age = new_age if __name__ == '__main__': tom = Person('汤姆', 10) tom.set_age(1000) print(tom) # 汤姆,1000, 修改了私有方法__age=1000
标签:__,name,self,面向对象,print,age,def From: https://www.cnblogs.com/SakuraYuanYuan/p/17892407.html