面向对象编程(Object-Oriented Programming,简称OOP)是一种通过组织对象来设计程序的编程方法。
自然界的东西大多以类而分,物以类聚‘
定义了对象的属性和方法,比如犬类里面有个中华田园犬(对象)5岁(属性)了它会吃狗粮(方法)
class Dog():
pass
注意俩点:
假如是狗类,每一个小狗就是一个对象
对象是类的实例化,具有类定义的属性与方法
小白是一只小狗,它就是狗的实例化
class Dog:
pass
创建类: dog1=Dog() 括号里可以有参数
类的属性和方法是核心部分,用于定义类的状态与行为
属性的使用语法:实例.属性名
例:
class Dog:
def __init__(self, name, color): # #初始化属性,self=对象自己,传进self本身初始化属性
self.name = name
self.color = color
dog1=Dog("hhh","blue")
print(dog1.color,dog1.name) #hhh,blue
调用: 实例.实例方法名(调用传参)
例:
class Dog:
def __init__(self, name, color): # #初始化属性,self=对象自己,传进self本身初始化属性
self.name = name
self.color = color
def barked(self,time):
print(f"一只叫{self.name} {self.color}的狗一直在叫了{time}分钟")
dog1=Dog("hhh","blue")
dog1.barked(20) #一只叫hhh blue的狗一直在叫了20分钟
作用:通常存储类创建的对象共有属性
注意:
创建:
class Dog:
age=5 #表示创建了一个Dog类里面的对象的age都是5
#类方法
class A:
v = 0
@classmethod
def set_v(cls, value): #cls为本类
cls.v = value
return cls.v
a=A
a2=A
print(a.set_v(6)) #6
print(A.v) #6
print(a2.v) #6 此时调用类方法将类中属性的值改变了 即将地址中的值改变
#静态方法
class Dog:
color = "blue"
@staticmethod
def func():
print("你好我是{cloor}")
dog1=Dog()
dog1.func() # 你好我是{cloor}
__new__():
负责创建对象和内存分配,在创建对象被调用时,返回一个对象实例(但通常不需要写new方法,python会自动调用基类objec的__new__():来创建对象
class Dog:
def __new__(cls, *args, **kwargs):
print("调用 __new__ 方法,创建对象")
return super().__new__(cls)
__init__():
对象被创建后来初始话对象的属性
class Dog:
def __init__(self, value): #self是对象本身
print("调用 __init__ 方法,初始化对象")
self.value = value
下面是一些常用的魔术方法
最为常见的是运算符重载
算数运算符重载
比如__add__方法
#魔术方法运算符重载
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
# def __str__(self):
# return f"Vector({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2
print(v3) #此时打印的为v3的地址 因为打印对象时python会调用对象的__str__和__repr__方法,若没有就会输出默认字符串就是对象的内存地址
__new__与__init__这俩个魔术方法用于对象的创建与初始化,和对象交互无关
具体可看上一小节有讲
__str__和__repr__方法用于将对象转化为字符串,方便输出调试
#显示对象的魔术方法
class func:
def __init__(self, width, height):
self.width = width
self.height = height
def __repr__(self):
return f"{self.width}, {self.height}"
def __str__(self):
return self.__repr__()
r = func(1, 2)
print(r) # 调用 __str__ 方法 print优先调用__str__方法
print(repr(r)) # 调用 __repr__ 方法
__len__返回对象的长度
#len
class MyList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
my_list = MyList([1, 2, 3])
print(len(my_list)) # 输出: 3
__getitem__定义对象支持索引操作(支持列表,元组那样的索引操作)
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
my_list = MyList([1, 2, 3, 4])
print(my_list[2]) # 输出: 3
__setitem__使对象支持索引赋值操作
class MyList:
def __init__(self, items):
self.items = items
def __setitem__(self, index, value):
self.items[index] = value
my_list = MyList([1, 2, 3])
my_list[1] = 10
print(my_list.items) # 输出: [1, 10, 3]
__del__主动调用可以销毁对象,但是__del__
方法的调用时机并不确定,因为它依赖于 Python 的垃圾回收机制
class MyClass:
def __init__(self, name):
self.name = name
print(f"对象 {name} 创建")
def __del__(self):
print(f"对象 {self.name} 被销毁")
obj = MyClass("Test")
del obj # 输出: 对象 Test 被销毁
__call__
使对象能像调用函数那样被调用
class Adder:
def __call__(self, a, b):
return a + b
# 创建 Adder 类的实例
adder = Adder()
# 像函数一样调用实例
result = adder(3, 5)
print(result) # 输出: 8
oop的四大基本特性是封装,继承,多态和抽象
class Dog:
def __init__(self, name, age):
self.__name = name # 私有属性
self.age = age
def get_name(self):
return self.__name
def set_name(self, name):
self.__name = name
dog = Dog('777', 5)
print(dog.get_name())
dog.set_name('666')
class dog1(dog,dog2,dog3): (有一个基类是单继承,有多个基类是多继承)
pass
class A:
def work(self):
print("A.work 被调用!")
class B(A):
'''B类继承自A类'''
def work(self):
print("B.work 被调用!!!")
pass
b = B()
b.work() # 请问调用谁? B
a = A()
a.work() # 请问调用谁? A #优先调用自己的方法
class Animal:
def speak(self):
print("Animal is speaking")
class Dog(Animal):
def speak(self):
print("Woof!")
class Cat(Animal):
def speak(self):
print("Meow!")
def animal_speak(animal): #通常使用此方法
animal.speak()
dog = Dog()
cat = Cat()
animal_speak(dog) # 输出 "Woof!"
animal_speak(cat) # 输出 "Meow!"
如果父类方法的功能不能满足需求,可以在子类重写父类的方法(与魔术方法类似)
class MyNumber:
def __init__(self, value): #初始化
self.data = value
def __str__(self):
return "%s" % self.data #自己重写
n1 = MyNumber("一只猫")
n2 = MyNumber("一只狗")
print("str(n2) ===>", str(n2)) #str(n2) ===> 一只狗
super()函数是调用父类(超类)的一个方法
在子类方法中使用 super().add() 调用父类中已被覆盖的方法
class A:
def add(self, x):
y = x+1
print(y)
class B(A):
def add(self, x):
print("子类方法")
super().add(x)
b = B()
b.add(2) # 3
使用 super(Child, obj).myMethod() 用于子类对象调用父类已被覆盖的方法
class Parent: # 定义父类
def myMethod(self):
print('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
super(Child, c).myMethod() # 用子类对象调用父类已被覆盖的方法
代码重用:避免在子类中重复父类的初始化代码。
正确初始化:确保父类的初始化逻辑即顺序
class Animal:
def __init__(self, name):
self.name = name
print(f"Animal {self.name} is created.")
class Dog(Animal):
def __init__(self, name, breed):
# 调用父类的构造函数
super().__init__(name)
self.breed = breed
print(f"Dog {self.name} of breed {self.breed} is created.")
# 创建 Dog 类的实例
dog = Dog("旺财", "中华田园犬")
#Animal 旺财 is created.
#Dog 旺财 of breed 中华田园犬 is created. 注意顺序即可