此篇文章是我在B站学习时所做的笔记,部分为亲自动手演示过的,方便复习用。此篇文章仅供学习参考。
提示:以下是本篇文章正文内容,下面案例可供参考
面向对象是一个编程思想(写代码的套路)
编程思想:
以上两种都属于写代码的套路(方法) ,最终目的都是为了将代码书写出来,只不过过程和思考方法不太一样.
面向对象的核心思想是 找一个对象去帮我们处理事情
在程序代码中 对象是由 类 创建的
类和对象,是 面向对象编程思想中非常重要的两个概念
苹果 —> 类
红苹果 ----> 类
张三嘴里正在吃的那个苹果 —> 对象
1, 类名 (给这多个事物起一个名字, 在代码中 满足大驼峰命名法(每个单词的首字母大写))
2, 属性 (事物的特征, 即有什么, 一般文字中的名词)
3, 方法 (事物的行为, 即做什么事, 一般是动词)
类的抽象(类的设计)
类的抽象,其实就是找到 类的 类名, 属性 和方法

类名: 人类(Person, People)
属性: 名字(name), 年龄(age), 身高(height)
方法: 跑步(run) 吃(eat)

类名: 狗类(Dog)
属性: 颜色(color) , 名字(name)
方法: 汪汪叫 (bark), 摇尾巴(shake)
class 类名:
# 在缩进中书写的内容,都是类中的代码
def 方法名(self): # 就是一个方法
pass
类名() # 创建一个对象, 这个对象在后续不能使用
# 创建的对象想要在后续的代码中继续使用, 需要使用一个变量,将这个对象保存起来
变量 = 类名() # 这个变量中保存的是对象的地址, 一般可以成为这个变量为对象
# 一个类可以创建多个对象, 只要出现 类名() 就是创建一个对象,每个对象的地址是不一样的
对象.方法名()
列表.sort()
列表.append()
需求:小猫爱吃鱼,小猫要喝水
类名: 猫类 Cat
属性: 暂无
方法: 吃鱼 (eat) 喝水 (drink )
"""
需求:小猫爱吃鱼,小猫要喝水, 定义不带属性的类
"""
class Cat:
# 在缩进中书写 方法
def eat(self): # self 会自动出现,暂不管
print('小猫爱吃鱼...')
def drink(self):
print('小猫要喝水----')
# 2. 创建对象
blue_cat = Cat()
# 3. 通过对象调用类中的方法
blue_cat.eat()
blue_cat.drink()
# 创建对象
black_cat = Cat()
black_cat.eat()
black_cat.drink()
Cat() # 是
a = black_cat # 不是
b = Cat # 不是
class Cat:
# 在缩进中书写 方法
def eat(self): # self 会自动出现,暂不管
print('小猫爱吃鱼...')
black_cat.eat()
1. 从函数的语法上讲, self是形参, 就可以是任意的变量名, 只不过我们习惯性将这个形参写作 self
2. self 是普通的形参, 但是在调用的时候没有传递实参值, 原因是, Python 解释器在执行代码的时候, 自动的将调用这个方法的对象 传递给了 self, 即 self 的本质是对象
3. 验证, 只需要确定 通过哪个对象调用, 对象的引用和 self 的引用是一样的
4. self 是函数中的局部变量, 直接创建的对象是全局变量
"""
需求:小猫爱吃鱼,小猫要喝水, 定义不带属性的类
"""
class Cat:
# 在缩进中书写 方法
def eat(self): # self 会自动出现,暂不管
print(f'{id(self)}, self')
print('小猫爱吃鱼...')
# 2. 创建对象
blue_cat = Cat()
print(f'{id(blue_cat)}, blue_cat')
# 3. 通过对象调用类中的方法
blue_cat.eat() # blue_cat 对象调用 eat 方法, 解释器就会将 blue_cat 对象传给 self
print('_*_' * 30)
# 创建对象
black_cat = Cat()
print(f"{id(black_cat)}, black_cat")
black_cat.eat() # black_cat 对象调用 eat 方法, 解释器就会将 black_cat 对象传给 self
对象.属性名 = 属性值
在内部方法中, self 是对象,
self.属性名 = 属性值
# 在类中添加属性一般写在 __init__ 方法中
对象.属性名 = 属性值 # 一般不使用
对象.属性名
在内部方法中, self 是对象,
self.属性名
对象.属性名 # 一般很少使用
class Cat:
# 在缩进中书写 方法
def eat(self): # self 会自动出现,暂不管
print(f'{id(self)}, self')
print(f'小猫{self.name} 爱吃鱼...')
# 2. 创建对象
blue_cat = Cat()
print(f'{id(blue_cat)}, blue_cat')
# 给 蓝猫添加 name 属性
blue_cat.name = '蓝猫'
# 3. 通过对象调用类中的方法
blue_cat.eat() # blue_cat 对象调用 eat 方法, 解释器就会将 blue_cat 对象传给 self
print('_*_' * 30)
# # 创建对象
black_cat = Cat()
black_cat.name = '黑猫'
print(f"{id(black_cat)}, black_cat")
black_cat.eat() # black_cat 对象调用 eat 方法, 解释器就会将 black_cat 对象传给 self
python 中有一类方法, 以两个下划线开头,两个下划线结尾,并且在满足某个条件的情况下, 会自动调用, 这类方法称为 魔法方法
学习:
创建对象之后会自动调用
- 给对象添加属性的, (初始化方法, 构造方法) 2. 某些代码, 在每次创建对象之后, 都要执行,就可以将这行代码写在 init 方法
- 不要写错了 2. 如果 init 方法中,存在出了 self 之外的参数, 在创建对象的时候必须传参
"""
猫类, 属性 name, age , show_info(输出属性信息)
"""
class Cat:
# 定义添加属性的方法
def __init__(self, name, age): # 这个方法是创建对象之后调用
self.name = name # 给对象添加 name 属性
self.age = age # 给对象添加 age 属性
# 输出属性信息
def show_info(self):
print(f'小猫的名字是: {self.name}, 年龄是: {self.age}')
# 创建对象,不要在自己类缩进中创建
# Cat() # 创建对象 ,会输出
blue_cat = Cat('蓝猫', 2)
blue = blue_cat
blue.show_info()
# 创建黑猫
black_cat = Cat('黑猫', 3)
black_cat.show_info()
使用 print(对象) 打印对象的时候 会自动调用
在这个方法中一般书写对象的 属性信息的, 即打印对象的时候想要查看什么信息,在这个方法中进行定义的
如果类中没有定义 str 方法, print(对象) ,默认输出对象的引用地址
这个方法必须返回 一个字符串
class Cat:
# 定义添加属性的方法
def __init__(self, n, age): # 这个方法是创建对象之后调用
self.name = n # 给对象添加 name 属性
self.age = age # 给对象添加 age 属性
def __str__(self):
# 方法必须返回一个字符串, 只要是字符串就行,
return f'小猫的名字是: {self.name}, 年龄是: {self.age}'
# 创建对象,不要在自己类缩进中创建
# Cat() # 创建对象 ,会输出
blue_cat = Cat('蓝猫', 2)
print(blue_cat)
# 创建黑猫
black_cat = Cat('黑猫', 3)
print(black_cat)
init 方法, 创建对象之后,会自动调用 (构造方法)
del 方法, 对象被删除销毁时, 自动调用的(遗言, 处理后事) (析构方法)
class Demo:
def __init__(self, name):
print('我是 __init__, 我被调用了 ')
self.name = name
def __del__(self):
print(f'{self.name} 没了, 给他处理后事...')
# Demo('a')
a = Demo('a')
b = Demo('b')
del a # 删除销毁 对象,
print('代码运行结束')
魔法方法:
init 初始化方法,
类名: 学生类 Student
属性: 姓名 name, 年龄 age
方法: 吃饭 eat 睡觉 sleep 过年year , str , init
class Student:
# 添加属性
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"姓名: {self.name}, 年龄: {self.age} 岁"
def eat(self):
print(f'{self.name} 要吃饭')
def sleep(self):
print(f'{self.name} 要睡觉')
def year(self):
self.age += 1
# 创建对象
xm = Student('小明', 18)
xh = Student('小红', 17)
print(xm)
print(xh)
xm.eat()
xm.sleep()
xm.year()
print(xm)
类名: 电脑类 Computer
属性: 品牌 brand , 价格 price [movie 电影的名字]
方法: play_movie
class Computer:
def __init__(self, brand, price):
self.brand = brand
self.price = price
def play_movie(self, movie):
print(f'{self.brand} 播放电影 {movie}')
# 创建对象
mi = Computer('小米', 4999)
mac = Computer('Mac', 16999)
mi.play_movie('葫芦娃')
mac.play_movie('变形金刚')
mi.play_movie('西游记')

# 定义家具类
class HouseItem:
"""家具类"""
def __init__(self, name, area):
"""添加属性的方法"""
self.name = name
self.area = area
def __str__(self):
return f'家具名字{self.name}, 占地面积 {self.area} 平米'
class House:
"""房子类"""
def __init__(self, name, area):
self.name = name # 户型
self.total_area = area # 总面积
self.free_area = area # 剩余面积
self.item_list = [] # 家具名称列表
def __str__(self):
return f"户型: {self.name}, 总面积:{self.total_area}平米, 剩余面积: {self.free_area} 平米, " \
f"家具名称列表: {self.item_list}"
def add_item(self, item): # item 表示的家具的对象
# 判断房子的剩余面积(self.free_area)和家具的占地面积(item.area)之间的关系
# self 表示的 房子对象, 缺少一个家具对象使用传参解决
if self.free_area > item.area:
# 添加家具, ---> 向列表中添加数据
self.item_list.append(item.name)
# 修改剩余面积
self.free_area -= item.area
print(f'{item.name} 添加成功')
else:
print('剩余面积不足, 换个大房子吧')
# 创建家具对象
bed = HouseItem('席梦思', 4)
chest = HouseItem('衣柜', 2)
table = HouseItem('餐桌', 1.5)
print(bed)
print(chest)
print(table)
# 创建房子对象
house = House('三室一厅', 150)
print(house)
# 添加 床
house.add_item(bed)
print(house)

class LoginPage:
def __init__(self, username, password, code):
self.username = username
self.password = password
self.code = code
self.btn = '登录'
def login(self):
print(f'1. 输入用户名 {self.username}')
print(f'2. 输入密码 {self.password}')
print(f'3. 输入验证码 {self.code}')
print(f"4. 点击按钮 {self.btn}")
login = LoginPage('admin', '123456', '8888')
login.login()

定义一个 Person 类, 属性 name, age(私有)
class Person:
def __init__(self, name, age):
self.name = name # 姓名
# 私有的本质, 是 Python 解释器执行代码,发现属性名或者方法名前有两个_, 会将这个名字重命名
# 会在这个名字的前边加上 _类名前缀,即 self.__age ===> self._Person__age
self.__age = age # 年龄, 将其定义为私有属性, 属性名前加上两个 _
def __str__(self): # 在类内部可以访问私有属性的
return f'名字: {self.name}, 年龄: {self.__age}'
xm = Person('小明', 18)
print(xm)
# 在类外部直接访问 age 属性
# print(xm.__age) # 会报错, 在类外部不能直接使用私有属性
# 直接修改 age 属性
xm.__age = 20 # 这个不是修改私有属性, 是添加了一个公有的属性 __age
print(xm) # 名字: 小明, 年龄: 18
print(xm._Person__age) # 能用但是不要用 18
xm._Person__age = 19
print(xm) # 名字: 小明, 年龄: 19
# class A(object):
class A: # 没有写父类,但也有父类, object, object 类是 Python 中最顶级(原始)的类
pass
class B(A): # 类 B, 继承类 A
pass

# 1. 定义一个 动物类, 吃
class Animal:
def eat(self):
print('要吃东西')
# 2. 定义一个 狗类, 继承动物类, 吃, 叫
class Dog(Animal):
def bark(self):
print('汪汪汪叫....')
# 3. 定义一个 哮天犬类, 继承 狗类
class XTQ(Dog):
pass
# 创建 动物类的对象
# ani = Animal()
# ani.eat()
# 创建狗类对象
# dog = Dog()
# dog.eat() # 调用父类中的方法
# dog.bark() # 调用自己类中方法
# 创建哮天犬类对象
xtq = XTQ()
xtq.bark() # 调用 父类 Dog 类的方法
xtq.eat() # 可以调用 父类的父类中的方法
python 中 对象.方法() 调用方法
重写: 在子类中定义了和父类中名字相同的方法, 就是重写
重写的原因: 父类中的方法,不能满足子类对象的需求,所以重写
重写之后的特点: 调用子类字节的方法, 不再调用父类中的方法
重写的方式:
>1. 覆盖(父类中功能完全抛弃,不要,重写书写)
>2. 扩展(父类中功能还调用,只是添加一些新的功能) (使用较多)
class Dog:
def bark(self):
print('汪汪汪叫.....')
class XTQ(Dog):
# XTQ 类bark 方法不再是汪汪汪叫, 改为 嗷嗷嗷叫
def bark(self):
print('嗷嗷嗷叫...')
xtq = XTQ()
xtq.bark()
class Dog:
def bark(self):
print('汪汪汪叫.....')
print('汪汪汪叫.....')
class XTQ(Dog):
# XTQ 类bark 方法不再是汪汪汪叫, 改为
# 1. 先 嗷嗷嗷叫(新功能) 2, 汪汪汪叫(父类中功能) 3. 嗷嗷嗷叫 (新功能)
def bark(self):
print('嗷嗷嗷叫...')
# 调用父类中的代码
super().bark() # print() 如果父类中代码有多行呢?
print('嗷嗷嗷叫...')
xtq = XTQ()
xtq.bark()
哪个对象调用方法, 就去自己的类中去查找这个方法, 找不到去父类中找
Python 中一切皆对象.
即 使用 class 定义的类 也是一个对象
只有 类对象 中存在一份
方法, 使用 def 关键字定义在类中的函数就是方法
# 在类中直接定义的方法 就是 实例方法
class Demo:
def func(self): # 参数一般写作 self,表示的是实例对象
pass
如果在方法中需要使用实例属性(即需要使用 self), 则这个方法必须定义为 实例方法
对象.方法名() # 不需要给 self 传参
# 在方法名字的上方书写 @classmethod 装饰器(使用 @classmethod 装饰的方法)
class Demo:
@classmethod
def func(cls): # 参数一般写作 cls, 表示的是类对象(即类名) class
pass
# 1. 通过类对象调用
类名.方法名() # 也不需要给 cls 传参, python 解释器自动传递
# 2. 通过实例对象调用
实例.方法名() # 也不需要给 cls 传参, python 解释器自动传递
# 在方法名字的上方书写 @staticmethod 装饰器(使用 @staticmethod 装饰的方法)
class Demo:
@staticmethod
def func(): # 一般没有参数
pass

# 1. 通过类对象调用
类名.方法名()
# 2. 通过实例对象调用
实例.方法名()
定义一个 Dog 类, 定义一个类属性 count,用来记录创建该类对象的个数. (即每创建一个对象,count 的值就要加1)实例属性 name
class Dog:
# 定义类属性
count = 0
# 定义实例属性, init 方法中
def __init__(self, name):
self.name = name # 实例属性
# 因为每创建一个对象,就会调用 init 方法, 就将个数加 1 的操作,写在 init 方法中
Dog.count += 1
# 在类外部
# 打印输出目前创建几个对象
print(Dog.count) # 0
# 创建一个对象
dog1 = Dog('小花')
# 打印输出目前创建几个对象
print(Dog.count) # 1
dog2 = Dog # 不是创建对象, 个数不变的
dog3 = dog1 # 不是创建对象, 个数不变的
print(Dog.count) # 1
dog4 = Dog('大黄') # 创建一个对象 , 个数 + 1
print(Dog.count) # 2
dog5 = Dog('小白')
print(Dog.count) # 3
# 补充, 可以使用 实例对象.类属性名 来获取类属性的值 (原因, 实例对象属性的查找顺序, 先在实例属性中找,找到直接使用
# 没有找到会去类属性中 找, 找到了可以使用, 没有找到 报错)
print(dog1.count) # 3
print(dog4.count) # 3
print(dog5.count) # 3

主程序步骤
# 1) 创建一个 Game 对象 小王
# 2) 小王玩一次游戏,
# 3) 查看历史最高分
# 4) 小王再玩一次游戏
# 5) 查看历史最高分
# 6) 查看游戏的帮助信息
import random
class Game:
# 类属性, 游戏的最高分
top_score = 0
def __init__(self, name):
# 定义实例属性 name
self.name = name
def show_help(self):
print('这是游戏的帮助信息')
def show_top_score(self):
print(f'游戏的最高分为 {Game.top_score}')
def start_game(self):
print(f'{self.name} 开始一局游戏, 游戏中 ...,', end='')
score = random.randint(10, 100) # 本次游戏的得分
print(f'本次游戏得分为 {score}')
if score > Game.top_score:
# 修改最高分
Game.top_score = score
xw = Game('小王')
xw.start_game()
xw.show_top_score()
xw.start_game()
xw.show_top_score()
xw.show_help()
@staticmethod
def show_help():
print('这是游戏的帮助信息')
@classmethod
def show_top_score(cls):
print(f'游戏的最高分为 {cls.top_score}')