day 18 - 面向对象 - 学习总结
01 编程思想
面向过程编程(穷人思想)
- 遇到问题马上想到怎么按照步骤一步一步解决这个问题
函数式编程(小资思想)
- 遇到问题先思考有没有一个已经存在的函数具备这个功能,如果有直接调用函数;没有就去创建具备这个功能的函数。
面向对象编程(富豪思想)
-
遇到问题就先思考有没有一个对象具备解决问题的能力,如果有就直接用。
-
没有对象就创建一个对象。没有类还要创建类。
02 认识类和对象
1. 类 – 类型、分类
-
类就是拥有相同功能相同属相的对象的集合 – 类是一个抽象的概念
-
对象就是类的实例(类的具体表现)
-
案例:
- 人是类 - 具体的一个人就是人的对象,比如:徐丹这个人
- 杯子是类 - 具体的一个杯子就是杯子的对象,比如:我的桌子的这个杯子
2. 定义类(创建类)
-
定义类的任务:用代码说清楚这个类是拥有哪些相同功能和哪些相同属性的对象的集合。
- 相同功能 – 用函数描述功能
- 相同属性 – 用变量描述属性
-
定义类的语法:
class 类名:
类的说明文档
类的内容( 有属性和方法组成)
说明:
class — 关键字,固定写法
类名 — 由程序员自己命名
要求:是标识符,不是关键字;
规范:见名知义;采用驼峰式命名(名字由多个单词组成,第二个单词首字母要大写),并且第一个字母大写);不能用系统函数名、类名、模块名
: — 固定写法
类的说明文档 — 多行注释
类的内容 — 由属性和方法组成
属性:定义在类中的变量
方法:定义在类中的函数
3. 创建对象
语法:类名( )
class Person: #定义类
"""人类"""
pass
p1 = Person() # 创建对象
p2 = Person()
print(p1) # <__main__.Person object at 0x00000193DF961190>
print(p2) # <__main__.Person object at 0x00000193DF961190>
方法就是定义在类中的函数,它是用来描述这个类具备的相同功能有哪些。
方法分为:对象方法、类方法、静态方法
1)对象方法!!!!!
怎么定义:直接定义在类中的函数就是对象方法
怎么调用:通过 对象. xxx( ) 的方式来调用
特点:自带参数 self ,通过对象调用这个方法的时候不用传参,因为系统会自动将当前对象传给self(谁调用self,self 就指向谁)。
使用场景:实现函数的功能只要需要用到对象时(需要对象属性),就一定用对象方法。
2)类方法
怎么定义:在定义函数前加装饰器:@classmethod
怎么调用:通过 类.xxx() 的方式来调用
特点:自带参数cls,通过类调用这个方法的时候cls不需要传参,系统会自动将当前类传给cls (谁调用指向谁)。
使用场景:实现函数的功能不需要用到对象时(需要对象属性)
3)静态方法
怎么定义:在定义函数前加装饰器:@staticmethod
怎么调用:通过 类.xxx() 的方式来调用
特点:无
使用场景:实现函数的功能不需要用到对象时(需要对象属性)
class A:
def func1(self):
print('对象方法', self)
def func11(self, x, y=2):
print(x, y)
@classmethod
def func2(cls):
print('类方法', cls)
@staticmethod
def func3():
print('静态方法')
a = A() # 创建A的对象
b = A()
print('a:', a) # a: <__main__.A object at 0x00000273F2987F70>
print('b:', b) # b: <__main__.A object at 0x00000273F2987F70>
# 用对象调用对象方法(给对象发func1的消息)
b.func1() # 对象方法 <__main__.A object at 0x00000273F2987F10>
a.func11(100, 200) # 100 200
a.func11(y=100, x=50) # 50 100
# 用类调用类方法
A.func2() # 类方法 <class '__main__.A'>
print('A:', A) # A: <class '__main__.A'>
# 用类调用静态方法
A.func3() # 静态方法
03 初始化方法
- __ init __ 方法 — 初始化方法
- 是python类中的一个魔法方法
- 魔法方法:类中所有名字以两个下划线开头和结尾的方法名。所有的魔法方法都不需要程序员去调用,系统会在特定情况下自动调用对应的魔法方法。
- 注意:python的类有哪些魔法方法是固定的,每个魔法方法什么时候调用也是固定的。
__ init __ 在通过类创建对象的时候会被自动调用。(每次通过类创建对象的时候系统都会自动调用类中的__ init __ 方法)
class A:
def __init__(self):
print('init方法被调用')
a=A() # init方法被调用
# 创建类的对象的时候是否需要参数,需要几个参数,由这个类中的__init__方法决定。
class B:
def __init__(self,x,y): # 有x,y参数
print('B的init被调用',x,y)
# a=B() # 报错!
# b=B(1) # 报错!
c=B(1,y=2) # B的init被调用,1,2 # 需要传参
04 属性 — 定义在类中的变量
- 属性分为类属性和对象属性。
1)类属性
怎么定义:直接定义在类中的变量:类名=xxx
怎么使用:通过 类.xxx 的形式来使用
什么时候用:如果属性值不会因为对象不同而不一样就定义成类属性,例如,圆的圆周率
2)对象属性!!!!!
怎么定义:以 self.属性名=值 的形式定义在__ init __ 方法中
怎么使用:通过 对象.xxx 的形式来使用对象属性
什么时候用:如果属性值会因为对象不同而不一样,就定义成对象属性,例如,圆的半径
class A:
# x、name是类属性
x = 10
name = '小明'
# y和m是对象属性
def __init__(self):
self.y = 20
self.m = 'abc'
# 通过类使用类属性
print(A.x, A.name) # 10 小明
A.name = '张三'
print(A.name) # 张三
# 通过对象使用对象属性
obj1 = A() # 定义对象
print(obj1.y, obj1.m) # 20 abc
# 对象属性赋默认值的方法:
# a. 赋一个固定的值
# b. 用一个没有默认值的形参赋值
# c. 用一个有默认值的形参赋值
class Person:
def __init__(self, name, gender='女'):
self.name = name
self.gender = gender
p1 = Person('张三', '男')
p2 = Person('小花')
print(p1.name, p2.name) # 张三 小花
# 案例:定义圆类,拥有属性半径和圆周率,方法:求圆的面积、求圆的周长
class Circle:
pi = 3.1415926
def __init__(self, r):
self.r = r
def get_area(self):
# self = c1
# self = c2
# 在实现函数功能的时候如果需要对象属性,就通过self来提供
return Circle.pi * self.r ** 2
c1 = Circle(1)
c2 = Circle(10)
print(c1.get_area()) # 3.1415926
print(c2.get_area()) # 314.15926
# 案例:求矩形的周长
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
def perimeter(self):
return (self.length + self.width) * 2
r1 = Rectangle(10, 5)
r2 = Rectangle(25, 15)
print(r1.perimeter()) # 30
print(r2.perimeter()) # 80