面向对象编程三大特性
封装
在属性名前面加两个连续的下划线, 这个属性就变成了私有属性
私有属性只能在类的内部使用, 不能在类的外部使用
'''
定义一个类, Person
有属性 姓名name, 体重weight
有方法run, 调用一次run方法weight少0.5公斤
有方法eat, 调用一次eat方法weight多1公斤
有方法show, 作用就是介绍自己, 其实就是显示name和weight的值
'''
class Person:
def __init__(self, name, weight):
self.name = name
self.weight = weight
def run(self):
self.weight -= 0.5
def eat(self):
self.weight += 1
def show(self):
print(f"我的名字叫{self.name}, 我的体重为{self.weight}")
xiaoming = Person("小明", 70)
xiaoming.show()
xiaoming.run()
xiaoming.run()
xiaoming.run()
xiaoming.show()
xiaoming.eat()
xiaoming.show()
xiaomei = Person("小美", 50)
xiaomei.show()
xiaomei.eat()
xiaomei.eat()
xiaomei.eat()
xiaomei.eat()
xiaomei.eat()
xiaomei.weight = 45
xiaomei.show()
'''
定义一个类, Person
有属性 姓名name, 体重weight
有方法run, 调用一次run方法weight少0.5公斤
有方法eat, 调用一次eat方法weight多1公斤
有方法show, 作用就是介绍自己, 其实就是显示name和weight的值
'''
class Person:
def __init__(self, name, weight):
self.name = name
self.__weight = weight
def run(self):
self.__weight -= 0.5
def eat(self):
self.__weight += 1
def show(self):
print(f"我的名字叫{self.name}, 我的体重为{self.__weight}")
xiaoming = Person("小明", 70)
xiaoming.show()
xiaoming.run()
xiaoming.run()
xiaoming.run()
xiaoming.show()
xiaoming.eat()
xiaoming.show()
xiaomei = Person("小美", 50)
xiaomei.show()
xiaomei.eat()
xiaomei.eat()
xiaomei.eat()
xiaomei.eat()
xiaomei.eat()
xiaomei.__weight = 45
xiaomei.show()
- 私有方法, 在方法名前面加两个连续的下划线, 方法就成为了私有方法
class Person:
def __secret(self):
print("我的秘密是, 睡觉磨牙打呼噜")
def show(self, password):
if password == "123456":
self.__secret()
else:
print("密码不对, 不告诉你我的小秘密哦")
p = Person()
p.show(input("请输入密码"))
继承
class 父类:
pass
class 子类(父类):
pass
class Animal:
def eat(self):
print("吃")
def sleep(self):
print("睡")
class Dog(Animal):
def run(self):
print("跑")
a = Animal()
a.sleep()
a.eat()
d = Dog()
d.eat()
d.sleep()
d.run()
class Animal:
def eat(self):
print("吃")
def sleep(self):
print("睡")
class Dog(Animal):
def run(self):
print("跑")
class Fish(Animal):
def swimming(self):
print("游水")
class Bird(Animal):
def fly(self):
print("飞")
'''
Animal类有两个方法, eat和sleep
Dog类有三个方法, eat和sleep还有run
Fish类有三个方法, eat和sleep还有swimming
Bird类有三个方法, eat和sleep还有fly
'''
a = Animal()
a.sleep()
a.eat()
d = Dog()
d.sleep()
d.eat()
d.run()
f = Fish()
f.sleep()
f.eat()
f.swimming()
b = Bird()
b.sleep()
b.eat()
b.fly()
class Animal:
def eat(self):
print("吃")
def sleep(self):
print("睡")
class Dog(Animal):
def run(self):
print("跑")
class ErHa(Dog):
def chaijia(self):
print("拆家")
class LangGou(Dog):
def yaoren(self):
print("咬人")
'''
类ErHa有eat, sleep, run和chaijia
类LangGou有有eat, sleep, run和yaoren
'''
e = ErHa()
e.sleep()
e.eat()
e.run()
e.chaijia()
l = LangGou()
l.sleep()
l.eat()
l.run()
l.yaoren()
Object类
- 在python3以上的版本中, 如果一个类没有明确的指定父类, 这个类继承自Object类
class A:
pass
方法的重写
- 当父类的方法不能满足子类的需求, 那么子类就要修改方法
覆盖
- 子类把父类的同名方法覆盖
- 子类中如果出现和父类同名的方法, 那么在子类中父类的同名方法就被覆盖了
class Animal:
def eat(self):
print("吃")
def sleep(self):
print("睡")
class Dog(Animal):
def eat(self):
print("吃肉")
a = Animal()
a.eat()
d = Dog()
d.sleep()
d.eat()
扩展super()
class Animal:
def eat(self):
print("吃")
class Dog(Animal):
def eat(self):
super().eat()
print("dog类自己的eat方法")
d = Dog()
d.eat()
属性的继承
class Animal:
def __init__(self, sex, age):
self.sex = sex
self.age = age
class Dog(Animal):
def show(self):
print(f"sex属性的值为{self.sex}, age属性的值为{self.age}")
d = Dog("男", 10)
d.show()
class Animal:
def __init__(self, sex, age):
self.sex = sex
self.age = age
class Dog(Animal):
def __init__(self, sex, age, name):
self.name = name
super().__init__(sex, age)
def show(self):
print(f"name属性的值为{self.name}, sex属性的值为{self.sex}, age属性的值为{self.age}")
d = Dog("男", 10, "tom")
d.show()
'''
类Animal有属性age
类Dog继承自Animal,有属性name
类Dog有方法show, 显示属性age和name
'''
class Animal:
def __init__(self, age):
self.age = age
class Dog(Animal):
def __init__(self, name, age):
self.name = name
super().__init__(age)
def show(self):
print(f"我的名字叫{self.name}, 我的年龄是{self.age}")
d = Dog("小狗", 3)
d.show()

父类的私有成员子类不能继承
- 父类中带有连续两个下划线的方法和属性都是私有的, 私有的成员不能继承给子类
class Animal:
def __init__(self):
self.__name = "动物"
def __my_func(self):
pass
class Dog(Animal):
pass
d = Dog()
多态
- 不同的子类对象, 调用相同的父类方法, 产生不同的执行结果
类A有方法show
类B1和B2都是继承自类A
B1的对象调用show方法
B2的对象调用show方法
两个对象调用的都是父类的show方法, 但执行的结果不一样
'''
class A:
def show(self):
print("show")
class B1(A):
pass
class B2(A):
pass
b1 = B1()
b1.show()
b2 = B2()
b2.show()
# 上面的代码不同的子类对象, 调用相同的父类方法, 执行结果也是一样, 这个不是多态
'''
class A:
def show(self):
self.my_func()
def my_func(self):
print("我是a")
class B1(A):
def my_func(self):
print("我是b1")
class B2(A):
def my_func(self):
print("我是b2")
b1 = B1()
b1.show()
b2 = B2()
b2.show()
类属性
- 不需要类的实例, 直接可以使用的属性
- 普通属性(实例属性)一定要在方法内部定义, 定义的时候self.属性名 = 值
- 类属性定义在类的内部, 但是在方法的外部, 定义的时候不需要使用self
- 类属性直接用类名.类属性名 使用
class A:
def __init__(self, name):
self.name = name
a = A("tom")
print(a.name)
class B:
name = "tom"
def __init__(self):
pass
print(B.name)
类方法
- 普通方法也叫实例方法,, 只能通过实例调用的方法
- 不需要实例, 直接通过类名.类方法名就能调用的方法
class 类名:
@classmethod
def 类方法(cls, 形参1, 形参2......):
pass
class A:
@classmethod
def my_func(cls):
print("我是类方法my_func")
A.my_func()
类方法的形参cls的作用
cls的作用一
class A:
age = 0
@classmethod
def show_age(cls):
print(cls.age)
@classmethod
def set_age(cls, age):
cls.age = age
A.set_age(200)
A.show_age()
cls的作用二
class A:
@classmethod
def my_func1(cls):
print("my_func1")
@classmethod
def my_func2(cls):
cls.my_func1()
A.my_func2()
class A:
__tmp = None
@classmethod
def create(cls):
if cls.__tmp is None:
cls.__tmp = A()
return cls.__tmp
else:
return cls.__tmp
def __init__(self):
print("类A被实例化了, 因为实例化的时候会自动调用__init__")
a = A.create()
b = A.create()
c = A.create()
静态方法
- 不需要实例, 直接可以通过类名.静态方法名 调用的方法
class 类名:
@staticmethod
def 静态方法名(形参1, 形参2........):
pass
class A:
@staticmethod
def help():
print("我是静态方法help")
A.help()
- 使用场景
- 如果一个项目, 有很多函数, 函数多了, 名字会重名, 可以把一些和类确实无关, 但有担心重名的函数, 做为类的静态方法使用
- 目的是避免因为函数重名带来的冲突
class A:
@staticmethod
def my_func():
print("aaaaaaaaaaaaaaa")
class B:
@staticmethod
def my_func():
print("bbbbbbbbbbbbbbbbbb")
A.my_func()
总结

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~