目录
一、概述
面向过程和面向对象
面向过程
我们解决问题的时候,会把所需要的步骤都列出来,然后按照步骤写代码挨个实现,这种过程化的叙事思维,就是面向过程思想.(基础班使用的都是面向过程的思想)
面向过程思考的重点在于步骤
面向对象
面向过程更讲事情的步骤,面向对象更讲事情的对象. 面向对象可以基于对象的共性做提炼,为软件工程的复用和扩展打好了坚实的基础. 这也是为什么在很多大型软件开发选型上,大多会使用面向对象编程.面向对象三大特性: 封装,继承,多态
二、类和对象
1. 概述
类
概述
类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物. 相当于一个洗衣机的设计图纸
定义类 注意:类名要满足标识符命名规则,同时遵循大驼峰命名习惯
class 类名():
代码
...
注意点
类的属性和功能都可以有N个,但要定义通用行为(功能).
类相当于函数的集合且函数必须有参数,但不需要传参(因为默认有个'self').
类的命名格式一般为大驼峰且见名知义.
类如果要工作必须创建对象.
对象
概述 相当于利用洗衣机图纸生产出N台洗衣机
定义对象 对象名 = 类名()
参数冒号后面接类型 此类型指的就是类.写完括号后接 箭头+类型,此类型指的是返回值类型.
调用对象 格式为" 对象名.类的功能名 "
类和对象的关系
用类去可以创建对象.
类是人为定义的,对象是自然定义的.
类是模板(洗衣机草图),是抽象的.
对象是实物(洗衣机),是具体的,可使用的.
2. 添加和获取对象属性
添加和获取对象属性
类外面创建
添加对象属性
对象名.属性名 = 值
仅仅在当前对象有效,该类的其他对象无效,一般不使用这种方式.
获取对象属性
对象名.属性名
类里面创建
添加对象属性
对象名.属性名 = 值
使用self添加 -- 哪里有self哪里就能添加 且需要谁调用谁才会有属性.
在内部添加属性--相当于self调用name 且self相当于对象.
获取对象属性
self.属性名
3. 魔法方法
init魔法方法 # 这是init魔法方法,它会在创建对象的时候自动执行.
def __init__(self,name,age):
self.name = name
self.age = age
适用于显示创建对象个数
# 创建对象
Stu1 = Stu("Ada",20)
# 使用属性
print(Stu1.name)
str魔法方法 # 这是str魔法方法,必须返回一个字符串,一般会用于返回该类的属性值.
def __str__(self):
return f"姓名是:{self.name},年龄是:{self.age}"
当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了__str__方法,那么就会打印从在这个方法中 return 的数据。
# 创建对象
Stu1 = Stu("Ada",20)
# 打印对象 -- 不想看到地址值,想看对象的属性值.
print(Stu1) # 姓名是:Ada,年龄是:20
repr魔法方法
# 这是repr魔法方法,在容器中的对象走这里-- 返回一个字符串.
# 对__str__有替代性, 但最好都写,这样可以做到兼容不同版本的Python.
def __repr__(self):
return f"颜色:{self.color},品牌:{self.brand}"
当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了__repr__方法,那么就会打印从在这个方法中 return 的数据。
# 创建对象
V1 = Vehicle("黑色",20,"丰田")
V2 = Vehicle("银色",40,"宝马")
V3 = Vehicle("蓝色",60,"奔驰")
# 打印对象
car_list = [V1,V2,V3]
print(car_list) # [颜色:黑色,品牌:丰田, 颜色:银色,品牌:宝马, 颜色:蓝色,品牌:奔驰]
__str__和__repr__的区别
# __str__ 与 __repr__ 的区别:二者都是返回对象的字符串表示。
# 不同的是:__str__ 返回的通常是让人容易阅读的格式。
__repr__返回的是面向Python解释器的,通常格式:<内容>
del魔法方法
# 当删除对象时,python解释器也会默认调用__del__()方法。
def __del__(self):
print(f'{self}对象已经被删除')
haier1 = Washer(10, 20)
del haier1 # <__main__.Washer object at 0x000001E28C8A7BB0>对象已经被删除
适用于显示删除对象的个数.
4. 类属性和实例属性
类属性
- 定义在类中,方法外.
- 属于类可以用类名调用.
- 所有对象共享一个类属性.可以访问不能修改.
实现
class Student():
school_name = "清华附中" # 类属性 位置在类中,函数外,它属于类对象,他同时被所有实例对象所共享.
def __init__(self, name):
self.name = name # 实例属性(要使用对象(self)类定义) 实例属性属于对象.每个对象单独有一份自己的实例属性.
def __str__(self):
return f"我的名字是{self.name},我的学校是{self.school_name}"
Student.school_name = "北大附中" # 因为类属性属于类,所以只有类对象才可以修改此属性.
实例属性
- 一般情况定义在__init__()函数中
- 属于对象.可以用对象名调用.
- 实例属性属于对象.每个对象单独有一份自己的实例属性.
5. 类方法和实例方法
类方法(@classmethod) 实例方法(常见定义的函数)
class Student():
school_name = "清华附中" # 类属性 位置在类中,函数外,它属于类对象,他同时被所有实例对象所共享.
@classmethod # 类方法
def show_school_name(cls):
print(f"学校名称是:{cls.school_name}")
def study(self): # 实例方法
print("好好学习,天天向上.")
def __init__(self, name):
self.name = name # 实例属性(要使用对象(self)类定义) 实例属性属于对象.每个对象单独有一份自己的实例属性.
def __str__(self):
return f"我的名字是{self.name},我的学校是{self.school_name}"
if __name__ == '__main__':
print(Student.school_name) # 类名可以直接调用类属性
Student.show_school_name() # 类名可以直接调用类方法
# Student.study() # 类名不可以调用实例方法
stu1 = Student("小明")
stu1.study() # 实例方法只能使用对象去调用
stu1.show_school_name() # 学校名称是:清华附中
三、多态
前提
有继承关系,
有方法重写,
父类引用指向子类对象(Python表现不明显).
实现
class Animal():
def eat(self):
print("动物吃饭")
class Dog(Animal):
def eat(self):
print("狗吃肉")
class Cat(Animal):
def eat(self):
print("猫吃鱼")
class Flower():
def eat(self):
print("小花喝水")
def feed_animal(animal: Animal):
animal.eat()
if __name__ == '__main__':
dog = Dog()
feed_animal(dog) # 狗吃肉
cat = Cat()
feed_animal(cat) # 猫吃鱼
flower = Flower()
feed_animal(flower)
# 小花喝水 虽然小花不是动物类型,但因为Python是弱类型语言,会报黄色警报,但不会报错,依然可以输出.
# 这就是Python中的鸭子类型:有只鸟走起来和叫起来都像鸭子,那么就姑且认为它就是鸭子.
四、继承
1. 概述
指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法.
作用: 提高代码的复用率, 减少重复代码的书写.
2. 单继承
单继承
实现
#定义父类
class Animal():
def __init__(self, name, color):
self.name = name
self.color = color
def run(self):
print(f"{self.name}可以跑!")
def sleep(self):
print(f"{self.name}可以睡觉!")
# 定义子类
class Cat(Animal):
def catch_mouse(self): # 子类自己的功能
print(f"{self.name}可以捉老鼠!")
if __name__ == '__main__':
cat1 = Cat("Tom", "蓝色") # 创建对象
print(cat1.name) # 调用名字属性
print(cat1.color) # 调用颜色属性
cat1.run() # 对象调用run功能
cat1.sleep() # 对象调用sleep功能
cat1.catch_mouse() # 对象调用捉老鼠功能
3. 多继承
概述 所谓多继承意思就是一个类同时继承了多个父类。
实现
# 定义父类1
class Fu():
def run(self):
print("跑步10公里/小时")
# 定义父类2
class Wang():
def run(self):
print("跑步15公里/小时")
# 定义子类
class Zi(Fu, Wang):
pass
if __name__ == '__main__':
zi1 = Zi() # 创建对象
zi1.run() # 跑步10公里/小时 当继承多个父类时,优先按照第一个父类的功能.
print(Zi.__mro__) # 为了方便且快速地看清继承关系和顺序,获取这个类的调用顺序。
# (<class '__main__.Zi'>, <class '__main__.Fu'>, <class '__main__.Wang'>, <class 'object'>)
4. 子类重写父类同名方法和属性
子类和父类具有同名属性和方法,默认使用子类的同名属性和方法
子类调用父类的同名方法和属性 父类名.父类方法名() 就可以调用父类方法
实现
class Fu():
def __init__(self,name): # 传name属性
self.name = name
print("父类初始化")
def fall_in_love(self):
print(f"{self.name}写一封情书")
class Zi(Fu):
def __init__(self,name): # 此处的name指的是子类的参数
super().__init__(name) # 相当于 调用父类 (子类传到父类的桥梁) super函数必须在类内使用.
print("子类初始化")
def fall_in_love(self):
# 先用父类的功能,super()表示父类的对象.
# super(Zi, self).fall_in_love() 与下一行作用相同
super().fall_in_love()
print("加微信")
if __name__ == '__main__':
Zi1 = Zi("小明") # 需要传入name属性
# Zi1.fall_in_love() # 默认调用子类自身的功能.
Fu.fall_in_love(Zi1) # 调用父类的功能. 用类名调用功能需要传参(传的是对象)
5. 多层继承
概述
多层继承就是有A和B, C继承了A和B, D继承了C, 那么D就有ABC全部功能.具有这样的多层级关系的就叫做多层继承.
实现
class A(object):
def show(self):
print('aaa')
class B():
def show(self):
print('bbb')
class C(A, B):
def show(self):
print('ccc')
class D(C):
def show1(self):
print('ddd')
if __name__ == '__main__':
print(D.__mro__) # (<class '__main__.D'>, <class '__main__.C'>,# <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
d = D()
d.show() # ccc
d.funa() # a的函数
6. 私有权限
概述 # 在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或实例方法不继承给子类。
# 设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __。 参数和方法一致.
# 获取和修改私有属性值
# 在Python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性值。
实现
class Fu():
def __init__(self, age):
self.__money = 10000 # 属性前面加上两个下划线表示私有属性
self.name = "hou"
self.__age = age
def set_age(self, age):
if 0 < age < 150:
self.__age = age
else:
print("年龄不合法!")
def get_age(self):
return self.__age
class Zi(Fu):
pass
if __name__ == '__main__':
Zi1 = Zi(18)
print(Zi1.name) # hou
# print(Zi1.__age) # 因年龄是私有的,无法直接打印.
print(Zi1.get_age()) # 这种方式可以拿取年龄 18
Zi1.set_age(100) # 这种方式可以设置年龄
print(Zi1.get_age()) # 打印设置的参数
总结
以上就是今天的内容,本文介绍了Python中面向对象的知识,这对于学习Python编程语言至关重要!