面向对象是一种编程思想,用这种思想为指导设计的程序,把数据和对数据的操作封装在一起组成类,通过类来创建对象,通过对象之间的交互来实现程序的功能。
一、认识
- 类
拥有相同功能和相同属性的对象和集合- 对象
类的实例
创建类
语法:
class 类名:
类的说明文档
类的内容
- class - 关键字,固定写法
- 类 名 - 程序员自己命名。采用驼峰式命名并且字母大写。(类名大写开头,
驼峰式 - 从第二个单词开始单词首字母大写)- : - 固定写法
- 说明文档 - 多行注释
- 类的内容 - 相同功能和相同属性。由方法(对象方法、类方法、静态方法)和属性(对象属性、类属性)组成
方法 - 定义在类中的函数
属性 - 定义在类中的变量
class Person:
"""
人类
"""
num = 61 # num 是属性
def eat(self): # eat 是方法
print('吃饭')
def sleep(self):
print('睡')
创建对象
语法:
类名() - 创建指定类对应的一个对象,并且将对象返回
p1 = Person()
p2 = Person()
print(p1)
print(p2)
# 运行结果为:
<__main__.Person object at 0x0000022C12F7B880>
<__main__.Person object at 0x0000022C12F2BF10>
二、方法
1、对象方法
怎么定义
将函数直接定义在类中
调用
通过对象来调用 - 对象.xxx()
特点
自带参数 self,通过对象调用对象方法的是 self 不需要传参,系统会自动将当前对象传给 self, (self:谁调用就指向谁)
什么时候用
如果实现函数的功能不需要对象属性需要类就是用类方法
2、类方法
怎么定义
定义函数前加装饰器 ‘@classmethod’
调用
通过类来调用 - 类名.xxx()
特点
自带参数 cls, 调用的时候不需要传参,系统自动将当前类传给 cls
什么时候用
如果实现函数的功能不需要对象属性需要类就是用类方法
3、静态方法
怎么定义
定义函数前加装饰器’@staticmethod’
class A:
def func1(self):
print('对象方法')
def func11(self, x, y):
print('对象方法2')
@classmethod
def func2(cls):
print('类方法')
@staticmethod
def func3():
print('静态方法')
a = A()
b = A()
print(f'a:{a}')
# 通过对象调用对象方法
a.func1()
a.func11(100, 200)
a.func11(x=100, y=200)
# 通过类调用类方法
A.func2()
# 通过类调用静态方法
A.func3()
4、魔法方法
方法名以__开头,并且以 __结尾的自带的方法,就是魔法方法
所有的魔法方法都会在特定的情况下被自动调用
常用的魔法方法
__init__ 创建类的对象的时候会自动调用类中的__init__方法
__repr__ 打印类的对线的时候会自动调用对象对应的类中的__repr__方法,来定制打印规则(函数的返回值是什么,对象的打印结果就是什么)
返回值必须是字符串
>>> class A:
... def __repr__(self):
... return 'abc'
...
>>> a = A()
>>> print(f'a:{a}')
a:abc
>>> class B:
... def __init__(self):
... print('init方法')
...
>>> b1 = B()
init方法
三、属性
1、 类属性
怎么创建
在类中直接定义一个变量,这个变量就是类属性
怎么使用
通过类来使用,包括获取和修改
什么时候用
当属性值不会因为对象不同而不一样的时候就使用类属性
2、 对象属性
怎么创建
以’self.属性名=值’的形式定义在类的__init__方法
怎么使用
通过对象来使用,对象.属性名
什么时候用
当属性值会因为对象不同而不一样的时候就使用类属性
类属性与对象属性
class A:
# x 是类属性
x = 100
# name 和 num 是对象属性
def __init__(self):
self.name = '小明'
self.num = 10
# 使用类属性
print(A.x)
# 修改类属性的值
A.x = 200
print(A.x)
a = A()
# 使用对象属性
print(a.name, a.num)
# 修改对象属性的值
a.name = '小花'
a.num = 11
print(a.name, a.num)
# 运行结果为:
100
200
小明 10
小花 11
对象属性赋初始值的方式
class Person:
def __init__(self, name, gender='男'):
self.name = name
self.age = 1
self.gender = gender
def __repr__(self):
# return f'name:{self.name}, age:{self.age}, gender{self.gender}'
return str(self.__dict__)
p1 = Person('小明')
p2 = Person('小花', '女')
print(p1)
print(p2)
# 运行结果为:
{'name': '小明', 'age': 1, 'gender': '男'}
{'name': '小花', 'age': 1, 'gender': '女'}
实现一个矩形类
class Rectangular:
def __init__(self, length, width):
self.l = length
self.w = width
def get_area(self):
return self.l * self.w
def get_perimeter(self):
return (self.w + self.l) * 2
def __repr__(self):
return f'长度:{self.l}, 宽度:{self.w}, ' \
f'面积:{self.get_area()}, 周长:{self.get_perimeter()}'
if __name__ == '__main__':
r1 = Rectangular(int(input('请输入长度:')), int(input('请输入宽度:')))
print(r1)
# 运行结果为:
请输入长度:>? 10
请输入宽度:>? 8
长度:10, 宽度:8, 面积:80, 周长:36
对象的对象属性支持增删改查
- 查 - 获取属性值
a. 对象.属性
获取指定属性的值
b. getattr(对象, 属性名)
获取指定属性的值
c. getattr(对象, 属性名, 默认值)
获取指定属性的值,属性不存在直接返沪默认值- 增、改
a. 对象.属性 = 值
当属性存在的时候修改指定属性对应的值,当属性不存在的时候给对象添加属性
b. setattr(对象, 属性名, 默认值)
当属性存在的时候修改指定属性对应的值,当属性不存在的时候给对象添加属性- 删
a. del 对象.属性
b. delattr(对象, 属性名)- 判断属性是否存在
hasattr()
存在,True;不存在,False
学生类
class Student:
def __init__(self, name, age=18, score=0):
self.name = name
self.age = age
self.score = score
def __repr__(self):
return str(self.__dict__)
增、改
stu1 = Student('小明', 12, 67)
stu2 = Student('小花', 19, 100)
print(stu1, stu2)
# {'name': '小明', 'age': 12, 'score': 67} {'name': '小花', 'age': 19, 'score': 100}
print(stu1.name) # 小明
print(getattr(stu1, 'name')) #小明
print(getattr(stu1, 'gender', '男')) # '男'
stu1.age = 22
print(stu1)
# {'name': '小明', 'age': 22, 'score': 67}
stu1.gender = '男'
print(stu1)
# {'name': '小明', 'age': 22, 'score': 67, 'gender': '男'}
setattr(stu1, 'study_id', '001')
print(stu1)
# {'name': '小明', 'age': 22, 'score': 67, 'gender': '男', 'study_id': '001'}
setattr(stu1, 'score', '76')
print(stu1)
# {'name': '小明', 'age': 22, 'score': '76', 'gender': '男', 'study_id': '001'}
删
print(stu1)
# {'name': '小明', 'age': 22, 'score': '76', 'gender': '男', 'study_id': '001'}
del stu1.age
print(stu1)
# {'name': '小明', 'score': '76', 'gender': '男', 'study_id': '001'}
delattr(stu1, 'name')
print(stu1)
# {'score': '76', 'gender': '男', 'study_id': '001'}
判断属性是否存在
print(hasattr(stu1, 'name'))
# False
print(hasattr(stu1, 'score'))
# True
if not hasattr(stu1, 'name'):
stu1.name = '小明'
四、继承
- 继承 - 让子类直接用拥有父类的属性和方法
父类就是一个大的类,子类是这个大的类下面的一个小的分类
- 继承的语法
class 类名(父类):
类的说明文档
类的内容
注意:定义类的时候如果没有写父类,这个类默认继承object(基类)
- 子类添加内容
子类在拥有父类的属性和方法的同时,往往需要由属于自己特有的一些属性和方法
添加类属性和方法直接在子类中定义新的类属性和新的方法
添加对象属性
需要在子类的__init__方法中通过super()去调用父类的__init__方法来继承父类的对象属性
父类A
class A:
a = 100
def __init__(self):
self.b = 10
self.c = 20
def func1(self):
print('对象方法')
@classmethod
def func2(cls):
print('类方法')
@staticmethod
def func3():
print('静态方法')
新建一个子类B继承A
class B(A):
pass
print(B.a)
# 100
x = B()
print(x.b, x.c)
# 10 20
x.func1()
# 对象方法
B.func2()
# 类方法
B.func3()
# 静态方法
新建一个子类C,继承A,并添加对象属性及方法
class C(A):
m = 11
def __init__(self):
super().__init__() # 调用当前类的父类的__init__()
self.name = '小明'
def func11(self):
print('C的对象方法')
@classmethod
def func22(cls):
print('C的类方法')
@staticmethod
def func33():
print('C的静态方法')
def func1(self):
print('C的对象方法2')
print(C.a, C.m)
# 100 11
x = C()
print(x.name)
# 小明
print(x.b, x.c)
#10 20