面向对象
1. 类和对象
- 定义类(创建类)
"""
定义类用代码描述清楚你这个类是拥有那些相同功能相同属性的对象的集合
功能 - 对应的是函数
属性 - 保存数据的变量 (在类中叫属性)
语法:
class 类名:
类的说明文档
类的内容
说明:
class - 关键字,固定写法
类名 - 程序员自己命名
要求:是标识符,不是关键字
规范:见名知义;驼峰式命名(单词之间采用首字母大写),首字母大写;不使用系统函数名、类名和模块名
: - 固定写法
类的说明文档 - 本质就是多行注释
类的内容 - 主要包括属性和方法
属性分为:类属性(类的字段)和对象属性
方法分为:对象方法、类方法和静态方法
注解:方法就是定义在类中的函数
"""
class Student:
"""
学生类
"""
pass
# 2.定义对象(创建对象)
"""
语法:类()
"""
stu1 = Student()
stu2 = Student()
print(stu1, stu2)
2.对象方法
- 方法
定义在类中的函数就是方法
- 对象方法
"""
怎么定义: 直接定义在类中的函数(定义函数前不用加装饰器)
怎么调用: 用对象来调用 - 对象.函数名()
特点:自带参数self,在调用的时候self不用传参,系统会自动当前对象传给self(谁调用self就指向谁)
"""
class Person:
"""人类"""
def sleep(self):
# self = p2
print(f'self:{self}')
print('睡觉')
def eat(self, food):
print(f'吃{food}')
p1 = Person() # 创建对象
p2 = Person()
print(f'p1:{p1}, p2{p2}')
p1.sleep()
p1.eat('面条')
p2.eat('小龙虾')
3. 构造方法和初始化方法
- 构造函数/构造方法
函数名和类相同,并且是用来创造对象的方法就是构造方法
python的构造函数在创建类的试试由系统自动创建,程序员只需要在创建对象的自动调用
- 初始化方法 (init)
"""
定义类的嘿嘿可以根据需求在类中添加对象方法: __init__,添加的时候要保证函数名是__init__,第一个参数是self
除此以外我们可以随意添加参数和函数体。
每次使用类创建对象的时候,系统会自动调用这个类中的__init__方法
调用构造方法创建对象的时候需不需要参数,需要几个参数,看这个类的__init__方法除了self以外有没有额外的参数
魔法方法:类中,方法名由__开头并且以__结尾的方法就是魔法方法。所有的魔法方法都是自动调用的
"""
class Dog:
def __init__(self):
print('__init__被调用')
# 下面的这个函数的定义由系统自动完成
"""
class Dog():
新建好的对象 = 创建对象并且申请内容保存对象
新建好的对象.__init__()
return 新建好的对象
"""
dog1 = Dog()
dog2 = Dog()
class Cat:
def __init__(self, name, age):
print('猫:__init__被调用')
print(f'name:{name}, age:{age}')
cat1 = Cat('小花', 3)
cat2 = Cat(name='豆豆', age=2)
cat3 = Cat('小梅', age=1)
- 补充:
def __init__(x, y):
print('自己的__init__被调用')
print(f'x:{x}, y:{y}')
def Cat(*args, **kwargs)
# args = (10, 20)
# kwargs = {'x': 20, 'y': 200}
__init__(*args,**kwargs) # __init__(10, 20), __init__(x=20, y=200)
c1 = Cat(10, 20)
c2 = Cat(x=20, y=200)
*x, y = 10, 20, 30, 40
def func1(*nums):
# *nums = 1, 2, 3, 4
pass
func1(1, 2, 3, 4)
def func2(a, b, c):
print(f'a:{a}, b:{b}, c:{c}')
# func2(100, 200, 300)
alist = (100, 200, 300)
func2(*alist) # func2(100, 200, 300)
aict1 = {'a': 10, 'b': 20, 'c': 30}
# **dict1 -> a=100, b=20, c==30
func2(**dict1) # func2(a=10, b=20, c=30)
3. 属性
- 属性
属性是用来描述类的数据特征。属性的本质是保存数据的变量
-
对象属性和类属性
-
类属性
怎么定义:直接定义在类中的变量就是类属性
怎么使用:通过类使用, 类.类属性
什么时候用:属性的值不会因为对象不同而不一样,这种属性就定义成类属性 -
对象属性
怎么定义:以’self.属性名=值’ 的形式定义在__init__方法中
怎么使用:通过对象来使用,对象.对象属性
什么时候用:属性的值不会因为对象不同而不一样,这种属性就定义成对象属性
-
class Person:
# num是类属性
num = 93
# name、age、gender是对象属性
def __init__(self):
self.name = '小梅'
self.age = 18
self.gender = '女孩子'
print(Person.num)
Person.num = 90
print(Person.num)
p1 = Person()
print(p1.name, p1.age, p1.gender) # 小梅 18 女孩子
p1.name = '小凤'
print(p1.name) # 小凤
- 对象属性赋初值的三种方式
方式1:赋一个固定的值,
方式2:使用没有默认值的参数赋值
方式3:使用默认值的参数
class Dog:
def __init__(self, name, color, breed='土狗', gender='母'):
self.breed = breed
self.name = name
self.gender = gender
self.color = color
self.age = 1 # 赋固定值
#__repr__ 方法在当前类的对象被打印的时候会被自动调用,这个方法的返回值(必须是字符串)是什么就打印什么
def __repr__(self):
# 打印谁,self就是谁
# return f'{self.name, self.breed, self.gender, self.color, self.age}'
return f'<{str(self.__dict__)[1:-1]}>'
dog1 = Dog('财财', '黄色')
print(f'dog1:{dog1}')
dog2 = Dog('花花', '白色', gender='公')
print(f'dog2:{dog2}')
练习:
# 练习:定义一个商品类,拥有属性:价格、名称、产地、类型、生成日期、保质期
# 要求:创建对象的时候价格、名称、生产日期必须赋值、产地默认温州、保证期默认1年、类型默认食品
# 打印对象的时候答应商品基本信息
class Goods:
def __init__(self, price, name, the_date_of):
self.price = price
self.name = name
self.origin = '温州'
self.type = '食品'
self.the_date_of = the_date_of
self.shelf_life = '一年'
def __repr__(self):
return f'<{str(self.__dict__)[1:-1]}>'
goods1 = Goods('泡面', 3, '2021-3-14')
print(goods1)
4.方法
-
对象方法
怎么定义:直接在内容定义函数(函数前不加装饰器)
怎么调用:对象.对象方法()
特点: 自带参数self,self不用传参,谁调用self就指向谁
什么时候用:如果实行函数的功能需要用到对象属性,一定是对象方法 -
类方法
怎么定义:在定义函数前加装饰器 @classmethod
怎么调用:类.类方法付()
特点: 自带参数cls, cls不用传参,系统将当前类传给cls (谁调用就指向谁)
什么时候用:实现函数的功能,在不需要对象属性的时候需要类就使用类方法 -
静态方法
怎么定义:在定义函数前加装饰器@staticmethod
怎么调用:类.静态方法
特点: 没有默认参数
什么时候用:实现函数的功能既不需要当前类的对象也不需要当前类,就使用静态方法
class Test:
def func1(self):
print('对象方法')
@classmethod
def func2(cls):
# cls = Test
print(f'cls: {cls}')
print('类方法')
@staticmethod
def func3():
print('静态方法')
t1 = Test()
# 用对象调用对象方法
t1.func1()
# 用类调用类方法
Test.func2()
print(f'Test:{Test}')
class Circle:
pi = 3.1415926
def __init__(self, radius)
self.radius = radius
def area(self):
return senlf.radius ** 2 * Circle.pi
@classmethod
def set_pi(cis, value):
cls.pi = value
c1 = Circle(1)
c2 = Circle(10)
print(c1.area())
print(c2.area())
作业
-
定义一个狗类和一个人类:
狗拥有属性:姓名、性别和品种 拥有方法:叫唤
人类拥有属性:姓名、年龄、狗 拥有方法:遛狗
class Dog:
def __init__(self, name, gender, varieties):
self.name = name
self.gender = gender
self.varieties = varieties
def func1(self):
print(f'{self.name:}汪汪汪')
dog1 = Dog('奶娃', '公', '土狗')
dog1.func1()
class Human:
def __init__(self, name, age, dog):
self.name = name
self.age = age
self.dog = dog
def god_name(self):
print(f'{self.name:}溜奶娃')
hunman1 = Human('坚果', '23', '奶娃')
hunman1.god_name()
- 定义一个矩形类,拥有属性:长、宽 拥有方法:求周长、求面积
class Rectangular:
def __init__(self, long, wide):
self.long = long
self.wide = wide
def perimeter(self):
return self.long * self.wide
def area(self):
return 2 * (self.long + self.wide)
func1 = Rectangular(15, 20)
print(f'面积:{func1.perimeter()}')
print(f'周长:{func1.area()}')
- 定义一个二维点类,拥有属性:x坐标、y坐标 拥有方法:求当前点到另外一个点的距离
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, point1):
return ((self.x - point1.x)**2) + ((self.y - point1.y)**2) ** 0.5
nexus = Point(5, 9)
nexus1 = Point(3, 5)
print(f'距离:{nexus.distance(nexus1)}')
- 定义一个圆类,拥有属性:半径、圆心 拥有方法:求圆的周长和面积、判断当前圆和另一个圆是否外切
class Round:
pi = 3.14
def __init__(self, radius, circle):
self.radius = radius
self.circle = circle
def perimeter(self):
return Round.pi * (self.radius * 2)
def area(self):
return Round.pi * (self.circle ** 2)
- 定义一个线段类,拥有属性:起点和终点, 拥有方法:获取线段的长度
class segment:
def __init__(self, origin, terminus):
self.origin = origin
self.terminus = terminus
def length(self):