面向过程与面向对象

类和对象
具有相同属性和行为的一类实体(对象)的抽象就是类
Python中一切皆对象
- 不同的数据类型属性不同的类
- 使用内置函数type()查看对象的数据类型
自定义类
语法结构
class 类名():
pass
创建对象
语法结构
对象名 = 类名()
类的组成
类的组成部分
- 类属性: 直接定义在类中,方法外的变量称为类属性,被该类的所有对象所共享,使用类名打点访问
- 实例属性: 定义在__init__方法中,使用self打点的变量称为实例属性

- 实例方法: 定义在类中,方法带在默认参数self的函数称为实例方法,使用对象名打点访问的方法

- 静态方法: 使用@staticmethod修饰的方法,使用类名直接访问的方法

- 类方法: 使用@classmethod修饰的方法,带有默认参数cls,使用类名打点访问

创建对象


动态绑定属性和方法
- 类是模板,可以创建N多个对象,每个对象的属性名是相同的,属性值是不同的
- Python是动态语言,在创建对象之后,可以动态地绑定属性和方法



访问权限控制
访问限制
- 对属性或方法添加单下划线、双下划线、首尾双下划线,限制访问权限
- 单下划线
- 以单下划线开头,表示protected受保护的成员,只允许类本身和子类进行访问,可以通过对象名去访问
- 双下划线
- 双下划线表示private私有的成员,只允许定义该方法的类本身访问,不能通过类的对象访问,但可以通过 “对象名._类名__xxx” 方式访问
- 首尾双下划线
class Student:
def __init__(self, name, age, gender):
self._name = name
self.__age = age
self.gender = gender
def _func1(self):
print("子类和本身可以访问")
def __func2(self):
print("只有定义的类可以访问")
def show(self):
self._func1()
self.__func2()
print(self._name)
print(self.__age)
if __name__ == '__main__':
stu = Student('ivan', 18, '男')
print(stu._name)
stu._func1()
print(stu._Student__age)
stu._Student__func2()
面向对象的三大特征
封装
class Student:
def __init__(self, name, age):
self.__name = name
self.__age = age
def show(self):
print(f"我叫:{self.__name}, 我今年:{self.__age}岁了")
if __name__ == '__main__':
stu = Student('inva', -23)
stu.show()
class Student:
def __init__(self, name):
self.__name = name
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if value < 0 or value > 130:
print("年龄不在正确的区间范围,设置的年龄范围应该是0-130之间")
self.__age = 18
else:
self.__age = value
def show(self):
print(f"我叫:{self.__name}, 我今年:{self.__age}岁了")
if __name__ == '__main__':
stu = Student('inva')
stu.age = -23
print(stu.age)
stu.show()
stu.age = 20
stu.show()
继承
- 实现继承,表示这个类拥有了被继承类的所有公有成员和受保护成员,被继承的类称为父类或基类,新的类称为子类或派生类
- 作用:实现代码的复用(重复使用),通过继承可以理顺类与类之间的关系
- 语法结构:
class 类名(sup[er_class_lst):
pass
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print(self.name, self.age)
class Student(Person):
def __init__(self, name, age, stuno):
super().__init__(name, age)
self.stuno = stuno
def des(self):
print(self.stuno)
class Doctor(Person):
def __init__(self, name, age, department):
Person.__init__(self, name, age)
self.department = department
def num(self):
print(self.department)
if __name__ == '__main__':
stu = Student('ivan', 20, 'st1001')
stu.show()
stu.des()
doc = Doctor('jack', 20, 'dt1001')
doc.show()
doc.num()
多继承
- 一个子类可以有多个“直接父类”,这样就具备了“多个父类”的特点
class FatherA:
def __init__(self, name):
self.name = name
def showA(self):
print("FatherA", self.name)
class FatherB:
def __init__(self, age):
self.age = age
def showB(self):
print("FatherB", self.age)
class Son(FatherA, FatherB):
def __init__(self, name, age, gender):
FatherA.__init__(self, name)
FatherB.__init__(self, age)
self.gender = gender
if __name__ == '__main__':
son = Son("James", 30, "Male")
son.showA()
son.showB()
方法重写
- 当父类(基类)中的某个方法不完全适合子类(派生类)时,就需要在子类中重写父类的方法
- 子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print(self.name, self.age)
class Student(Person):
def __init__(self, name, age, stuno):
super().__init__(name, age)
self.stuno = stuno
def show(self):
super().show()
print(f"我的学号是:{self.stuno}")
class Doctor(Person):
def __init__(self, name, age, department):
Person.__init__(self, name, age)
self.department = department
def show(self):
print(f"我叫{self.name},年龄是:{self.age},我的工作科室是:{self.department}")
if __name__ == '__main__':
stu = Student('ivan', 20, 'st1001')
stu.show()
doc = Doctor('jack', 20, 'dt1001')
doc.show()
object类
- object类是所有类的父类,因此所有类都有object类的属性和方法
- 内置函数 dir() 可以查看指定对象所有属性
- object有一个 str() 方法,用于返回一个对于“对象的描述”,对应于内置函数 str() 经常用于print()方法,帮我们查看对象的信息,所以我们经常会对 str() 进行重写
print(dir(object))
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print(f"大家好,我叫{self.name},今年{self.age}岁了")
def __str__(self):
return '这是一个人类,具有name和age两个实例属性'
if __name__ == '__main__':
per = Person('ivan', 20)
per.show()
print(dir(per))
print(per)
print(per.__str__())
print(per.__dir__())
print(dir(per))
多态
- 简单地说,多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,再运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法
- Python语言中的多态,不关心对象的数据类型,不关心是否具有继承关系,只关心对象的行为(方法)
class Person:
def eat(self):
print('人吃饭')
class Cat:
def eat(self):
print('猫吃鱼')
class Dog:
def eat(self):
print('狗吃骨头')
def fun(obj):
obj.eat()
if __name__ == '__main__':
per = Person()
cat = Cat()
dog = Dog()
fun(per)
fun(cat)
fun(dog)
特殊方法和特殊属性
特殊方法
- Python中的运算符实际上是通过调用特殊方法实现的

特殊属性
