面向对象基础
一、编程思想
1.面向过程编程:基本语法、逻辑
2.函数式编程:掌握函数
遇到问题先思考有没有已经存在的函数具备解决这个问题的能力,如果有直接调用;没有自己创建一个这样的函数。
3.面向对象编程:类、对象(变量、函数)
二、类和对象
1.认识类和对象
-
类和对象的概念
类:拥有相同功能和属性的对象的集合; - 抽象的概念。
对象:类的实例。 - 类具体的表现。
# 举例 人是类,具体的一个人就是它的对象, 电脑是类,自己桌子上的电脑 杯子是类,自己桌子上的杯子
-
定义类(创建类)
1)用代码描述类是拥有哪些相同功能和属性的对象的集合。
2)功能:函数(动作)
3)属性:保存变量的数据
4)语法:
class 类名: 类的说明文档 类的内容
5)说明
a.class - 关键字;固定写法
扫描二维码关注公众号,回复: 14490540 查看本文章b.类名 - 程序员自己命名
规范:见名知义,采用驼峰式命名并且首字母大写。(类名大写开头;驼峰式指的是从第二个单词开始单词首字母大写)
c.: - 固定写法
d.类的说明文档 - 多行注释
e.类的内容 - 相同功能和相同属性。
由方法(对象方法、类方法、静态方法)和属性(对象属性、类属性)组成
方法:定义在类中的函数;属性:定义在类中的变量
# 例子 class Person: """人类""" num = 61 # num是属性 def eat(self): # eat是方法 print('吃饭') def sleep(self): # sleep是方法 print('睡觉')
-
创建对象
类名() - 创建指定类的一个对象,并且将对象返回
class Person: """人类""" num = 61 # num是属性 def eat(self): # eat是方法 print('吃饭') def sleep(self): # sleep是方法 print('睡觉') p1 = Person() p2 = Person() print(p1) # <__main__.Person object at 0x0000015A0773D5C8> print(p2) # <__main__.Person object at 0x0000015A0773D608> # __main__表示当前模块
2.类中的方法
方法:定义在类中的函数,用来描述类具备的功能。
-
对象方法
a.定义:将函数直接定义在类中
b.调用:通过对象来调用 - 对象.xxx()
c.特点:自带参数self,通过对象调用对象方法时,参数self不需要传参,系统会将当前对象传给self。(self,谁调用就指向谁)
d.什么时候用:如果实现函数的功能需要用到对象属性就使用对象方法。
class A: def func1(self): print(f'self: { self}') print('对象方法') def func11(self, x, y): print(f'self: { self}') print('对象方法2') # 通过对象调用对象方法,调用不会传参,调用时系统会自动传参 a = A() a.func1() # self: <__main__.A object at 0x00000221B568D6C8> # 对象方法 # 自己定义了参数 b = A() b.func11(100, 200) # self: <__main__.A object at 0x000001D23363D908> # 对象方法2
-
类方法
a.定义:定义函数前加装饰器’@classmethod’
b.调用:通过类来调用 - 类名.xxx()
c.特点:自带参数cls,通过类调用方法时,参数cls不需要传参,系统会将当前类传给cls。(cls,谁调用就指向谁)
d.什么时候用:如果实现函数的功能不需要用到对象属性需要类属性就使用类方法。
class A: # 类方法 @classmethod def func2(cls): print('类方法') # 通过类调用类方法 A.func2() # 类方法
-
静态方法
a.定义:定义函数前加装饰器’@staticmethod’
b.调用:通过类来调用 - 类名.xxx()
c.特点:没有特点
d.什么时候用:如果实现函数的功能不需要对象属性和类属性就使用静态方法。
class A: # 静态方法 @staticmethod def func3(): print('静态方法') # 通过类调用静态方法 A.func3() # 静态方法
-
初始化方法之魔法方法
魔法方法的概念:方法以__开头且以__结尾的自带的方法,就是魔法。所有的魔法方法都会在特定的情况下被自动调用。
a.__repr__ ----打印类的对象时自动调用对象对应的类中的__repr__方法,来定制打印规则(函数的返回值返回什么,对象打印结果就是什么)。返回值必须是字符串!
class A: def __repr__(self): return 'abc' a = A() print(a) # abc
b.__init__----每次创建类的对象时会自动调用类中的__init__方法
class B: def __init__(self): print('init方法') # 构造函数 b1 = B() # init方法(创建类就调用了) b2 = B() # init方法(创建类就调用了) # 参数添加 class C: # 在类中添加__init__方法时,除了方法名和方法类型不能动,可以随意添加参数和添加函数体。 def __init__(self, x, y): print('C的init方法', x, y) # 自己加了没有默认值的参数,必须传参,位置参数和关键字参数都可。 # 创建类的对象时需要几个参数,由类中的__init__方法决定。 c1 = C(1, 2) # C的init方法 1 2
3.属性
-
类属性
a.创建:在类中直接定义一个变量,这个变量就是类属性
b.使用:通过类来使用 - 类.xxx
c.什么时候用:当属性值不会因为对象不同而不一样时使用类属性。
class A: # x是类属性 x = 100 # 直接使用 print(A.x) # 100 # 修改类属性的值 A.x = 200 print(A.x) # 200
-
对象属性
a.创建:以'self.属性名 = 值'的形式定义在类的__init__方法中。 b.使用:通过对象使用 - 对象.属性名 c.什么时候用:当属性值会因为对象不同而不一样时使用类属性。
class B: # x是类属性 x = 10 def __init__(self): # name和num是对象属性 self.name = '小明' self.num = '123456789' b = B() # 使用对象属性 print(b.name, b.num) # 小明 123456789 # 修改对象属性的值 b.name = '小花' b.num = '112' print(b.name, b.num) # 小花 112
-
对象属性赋初值的方式
a.通过没有默认值的参数来赋值
b.赋固定值,创建对象时不能修改
c.使用有默认值的参数来赋值,创建对象时可以修改
注意:
self.__dict__在__repr__函数中使用表示返回所有的对象属性组成的字典。
class Person: def __init__(self, name, gender = '男'): self.name = name # 通过没有默认值的参数来赋值 self.age = 1 # 赋固定值,创建对象时不能修改 self.gender = gender # 使用有默认值的参数来赋值,创建对象时可以修改 def __repr__(self): return f'<{ str(self.__dict__)[1:-1]}>' p1 = Person('小明') print(p1.name, p1.age, p1.gender) # 小明 1 男 print(p1) # <'name': '小明', 'age': 1, 'gender': '男'> p2 = Person('小花', '女') print(p2.name, p2.age, p2.gender) # 小花 1 女 print(p2) # <'name': '小花', 'age': 1, 'gender': '女'>
-
属性的增删改查
注意:attr相关函数可以动态操作对象属性
-
查:获取属性值
a. 对象.属性 - 获取指定属性的值,属性不存在报错
b. getattr(对象,属性名) - 获取指定属性的值,属性不存在报错
c. getattr(对象,属性名,默认值) - 获取指定属性的值,属性不存在返回默认值
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, 99) # a.对象.属性 - 获取指定属性的值,属性不存在报错 print(stu1.name) # b.getattr(对象,属性名) - 获取指定属性的值,属性不存在报错 print(getattr(stu1, 'name')) # c.getattr(对象,属性名,默认值) - 获取指定属性的值,属性不存在返回默认值 print(getattr(stu1, 'gender', '男')) # 对象.属性和getattr(对象,属性名)的区别 # print(stu1.gender) # 报错! print(getattr(stu1, 'gender', '男'))
-
增、改
a. 对象.属性 = 值 - 当属性存在时,修改指定属性对应的值;当属性不存在时,给对象添加属性。
b. setattr(对象,属性名,值) - 当属性存在时,修改指定属性对应的值;当属性不存在时,给对象添加属性。
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, 99) # a.对象.属性 = 值 - 当属性存在时,修改指定属性对应的值;当属性不存在时,给对象添加属性。 print(stu1) # {'name': '小明', 'age': 12, 'score': 67} stu1.age = 22 # 修改age的值 print(stu1) # {'name': '小明', 'age': 22, 'score': 67} stu1.gender = '男' # 增加gender属性和值 print(stu1) # {'name': '小明', 'age': 22, 'score': 67, 'gender': '男'} # b.setattr(对象,属性名,值) - 当属性存在时,修改指定属性对应的值;当属性不存在时,给对象添加属性。 setattr(stu1, 'stu_id', '001') # 增加stu_id属性和值 print(stu1) # {'name': '小明', 'age': 22, 'score': 67, 'gender': '男', 'stu_id': '001'} setattr(stu1, 'score', 76) # 修改score的值 print(stu1) # {'name': '小明', 'age': 22, 'score': 76, 'gender': '男', 'stu_id': '001'}
-
删
a. del 对象.属性 - 删除指定属性
b. delattr(对象, 属性名)
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) stu1.gender = '男' setattr(stu1, 'stu_id', '001') print(stu1) # {'name': '小明', 'age': 22, 'score': 76, 'gender': '男', 'stu_id': '001'} del stu1.age print(stu1) # {'name': '小明', 'score': 76, 'gender': '男', 'stu_id': '001'} delattr(stu1, 'name') print(stu1) # {'score': 76, 'gender': '男', 'stu_id': '001'}
-
判断属性是否存在 - hasattr(对象, 属性名)
# 和上面增删改创建的类一样 # stu1: {'score': 76, 'gender': '男', 'stu_id': '001'} print(hasattr(stu1, 'name')) # False print(hasattr(stu1, 'score')) # True
-
4.继承
-
概念
继承:让子类直接拥有父类的属性和方法。
父类:大的类;子类:大的类(父类)下面的一个小的分类。
-
语法
class 类名(父类): 类的说明文档 类的内容 注意:定义类时如果没有写父类,这个类默认继承object(基类)
class A: a = 10 def __init__(self): self.b = 20 self.c = 30 def func1(self): print('对象方法') @classmethod def func2(cls): print('类方法') @staticmethod def func3(): print('静态方法') class B(A): # B继承A pass print(B.a) # 10 x = B() print(x.b, x.c) # 20 30 x.func1() # 对象方法 B.func2() # 类方法 B.func3() # 静态方法
-
子类添加内容
1)添加类属性和方法 直接在子类中定义新的类属性和新的方法 2)添加对象属性 在子类的__init__函数中先添加:'super().__init__()'用来调用当前类的父类的__init__(), 然后再定义自己的对象属性
class A: a = 10 def __init__(self): self.b = 20 self.c = 30 def func1(self): print('对象方法') @classmethod def func2(cls): print('类方法') @staticmethod def func3(): print('静态方法') class C(A): # 添加类属性 m = 11 def __init__(self, age=18, gender='男'): # 添加对象属性 super().__init__() # 调用当前类的父类的__init__() self.name = 'xiaoming' self.age = age self.gender = gender # 添加对象方法 def fun11(self): print('C的对象方法') # 添加类方法 @classmethod def func22(cls): print('C的类方法') # 添加静态方法 @staticmethod def func33(): print('C的静态方法') # 如果重名,调用子类就是子类中的方法,调用父类就是父类的方法。 # 打印类的对象时的输出内容 def __repr__(self): return str(self.__dict__) print(C.a, C.m) # 10 11 x = C() print(x.b, x.c) # 20 30 info = C(19, '女') print(info) # {'b': 20, 'c': 30, 'name': 'xiaoming', 'age': 19, 'gender': '女'}