OOP的四大基本特性是封装、继承、多态和抽象。
__init__
方法初始化属性,并通过方法来操作这些属性。__
开头的属性或方法是私有的,在子类和类外部无法直接使用# 继承
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(f"{self.name} 今年{self.age}岁,调用了吃东西方法")
p1=Person("jack",1)
p1.eat()
# class Student():
# def __init__(self, name, age, school):
# self.name = name
# self.age = age
# self.school = school
# def eat(self):
# print(f"{self.name} 今年{self.age}岁,调用了吃东西方法")
# def study(self):
# print(f"{self.name} 今年{self.age}岁,调用了学习方法")
class Student(Person):
def __init__(self, name, age, school):
super().__init__(name, age)
self.school = school
def study(self):
print(f"{self.name} 今年{self.age}岁,调用了学习方法")
s1=Student("jack",1,"学前班")
s2=Student("marry",20,"大学")
s2.study()
s2.eat()
jack 今年1岁,调用了吃东西方法
marry 今年20岁,调用了学习方法
marry 今年20岁,调用了吃东西方法
儿子继承了父亲,父亲派生了儿子~
Python中所有的类最终都继承自内置的object类。
class Father():
def __init__(self):
self.money = 1000
def fn(self):
print("我是父亲的fn方法")
class Mother():
def __init__(self):
self.car = "BYD"
def fm(self):
print("我是母亲的fm方法")
class Son(Father,Mother):
def __init__(self):
# super().__init__()
Father.__init__(self)
Mother.__init__(self)
self.school = "学校"
s1=Son()
print(s1.money,s1.car,s1.school)
s1.fn()
s1.fm()
1000 BYD 学校
我是父亲的fn方法
我是母亲的fm方法
1.2.4覆盖
在子类中实现与基类同名的方法,我们叫覆盖
作用:
覆盖示例
#覆盖
class Animal:
x=1000
def __init__(self,name):
self.name=name
def eat(self):
print("eat")
def sleep(self):
print("sleep")
def run(self):
print("run")
class Cat(Animal):
def __init__(self,name,age):
super().__init__(name)
self.age=age
self.x=6000
def eat(self):
print("Cat.eat")
def sleep(self):
print("Cat.sleep")
def run(self):
print("Cat.run")
c1=Cat("小花",3)
print(c1.x)
print(c1.name)
print(c1.age)
c1.eat()
c1.sleep()
c1.run()
6000
小花
3
Cat.eat
Cat.sleep
Cat.run
#多态
class Animal():
def run(self):
print('动物在奔跑')
class Dog(Animal):
def run(self):
print('狗在奔跑')
def dog_eat(self):
print('狗在吃东西')
class Cat(Animal):
def run(self):
print('猫在奔跑')
def cat_eat(self):
print('猫在吃东西')
class Fish(Animal):
def youyong(self):
print('鱼在游动')
def fn(animal):
if isinstance(animal,Animal):
animal.run()
dig = Dog()
cat = Cat()
fish = Fish()
fn(dig)
fn(cat)
fn(fish)
print( isinstance(dig,Dog))
print( isinstance(cat,Dog))
print( isinstance(fish,Fish))
print( isinstance(dig,Animal))
print( isinstance(cat,Animal))
print( isinstance(fish,Animal))
狗在奔跑
猫在奔跑
动物在奔跑
True
False
True
True
True
True
#对象对成员的操作
class Person:
def __init__(self,name,age):
self.name=name
self.age=age
def show(self):
print(self.name,self.age)
p1=Person('张三',20)
print(p1.name,p1.age)
# print(p1.money)访问对象的成员如果是取值操作,就会去继承链中找 没找到就报错
p1.age=30
print(p1.age)
p1.money=1000#访问对象的成员如果是存值操作,不会去继承链 直接在当前对象中找 找到了就更新 没找到就添加
print(p1.name,p1.age,p1.money)
张三 20
30
张三 30 1000
#私有属性
# __属性名
class Person:
__x=100
def __init__(self):
self.__y=30
def fn(self):
print("私有属性",self.__x)
print("私有属性",self.__y)
def tool(self):
self.__x=666
self.__y=666
p1=Person()
# print(p1.__x)#私有属性不能在类外面直接访问
# print(p1.__y)
p1.fn()
p1.tool()
p1.fn()
私有属性 100
私有属性 30
私有属性 666
私有属性 666
运算符重载是指让自定义的类生成的对象(实例)能够使用运算符进行操作
运算符重载的作用
运算符重载说明:
运算符重载方法的参数已经有固定的含义,不建议改变原有的意义
方法名 | 运算符和表达式 | 说明 |
---|---|---|
__add__(self, rhs) |
self + rhs | 加法 |
__sub__(self, rhs) |
self - rhs | 减法 |
__mul__(self, rhs) |
self * rhs | 乘法 |
__truediv__(self, rhs) |
self / rhs | 除法 |
__floordiv__(self, rhs) |
self // rhs | 地板除 |
__mod__(self, rhs) |
self % rhs | 取模(求余) |
__pow__(self, rhs) |
self ** rhs | 幂 |
class Box:
def __init__(self, length, width, height):
self.length = length
self.width = width
self.height = height
def __add__(self, other):
# 实现两个Box对象的相加操作
new_length = self.length + other.length
new_width = self.width + other.width
new_height = self.height + other.height
return Box(new_length, new_width, new_height)
def __sub__(self, other):
# 实现两个Box对象的相减操作
new_length = self.length - other.length
new_width = self.width - other.width
new_height = self.height - other.height
return Box(new_length, new_width, new_height)
def __mul__(self, scalar):
# 实现两个Box对象的相乘操作
new_length = self.length * scalar
new_width = self.width * scalar
new_height = self.height * scalar
return Box(new_length, new_width, new_height)
def __truediv__(self, scalar):
# 实现两个Box对象的相除操作
new_length = self.length / scalar
new_width = self.width / scalar
new_height = self.height / scalar
return Box(new_length, new_width, new_height)
def __floordiv__(self, scalar):
# 实现两个Box对象的整除操作
new_length = self.length // scalar
new_width = self.width // scalar
new_height = self.height // scalar
return Box(new_length, new_width, new_height)
def __mod__(self, scalar):
# 实现两个Box对象的取余操作
new_length = self.length % scalar
new_width = self.width % scalar
new_height = self.height % scalar
return Box(new_length, new_width, new_height)
def __pow__(self, exponent):
# 实现两个Box对象的幂运算操作
new_length = self.length ** exponent
new_width = self.width ** exponent
new_height = self.height ** exponent
return Box(new_length, new_width, new_height)
def __str__(self):
# 定义对象的字符串表示
return f"Box(length={self.length}, width={self.width}, height={self.height})"
b1=Box(1,2,3)
print(b1)
print(b1+b1)
print(b1-b1)
print(b1*2)
print(b1/2)
print(b1//2)
print(b1%2)
print(b1**2)
Box(length=1, width=2, height=3)
Box(length=2, width=4, height=6)
Box(length=0, width=0, height=0)
Box(length=2, width=4, height=6)
Box(length=0.5, width=1.0, height=1.5)
Box(length=0, width=1, height=1)
Box(length=1, width=0, height=1)
Box(length=1, width=4, height=9)
super() 函数是用于调用父类(超类)的一个方法
在子类方法中使用 s u p e r ( ) . a d d ( ) super().add() super().add() 调用父类中已被覆盖的方法
使用 s u p e r ( C h i l d , o b j ) . m y M e t h o d ( ) super(Child, obj).myMethod() super(Child,obj).myMethod() 用于子类对象调用父类已被覆盖的方法
#super()
class Box:
def fn(self):
print("很多很好的代码")
def fn2(self):
print("很好的代码")
class Box2(Box):
# 重写了父类的fn方法 但是父类这10w行很好 不想重新写10w 然后再多加1w行
def fn(self):
#super(Box2,self).fn(),这是一个比较全面的写法,现在变得简洁
super().fn()
# super().fn()#super()表示调用父类 super().fn() 类似 Box().fn()
print("新写的代码")
b=Box2()
b.fn()
很多很好的代码
新写的代码
class Box:
x=100
def fn(self):
print("Box的fn方法",self.x)
class Box2(Box):
x=300
def fn(self):
print("Box2的fn方法",self.x)
# b21=Box2()
# b22=Box2()
# b21.x=500
# b22.x=600
# b21.fn()
# b22.fn()
b2=Box2()
b2.x=400
# b2.fn()
super(Box2,b2).fn()#用子类的b2对象 调用父类的fn方法
#总结:
# 1.执行Box2父类的fn函数 把b2作为第一个参数self传入进去
# 2.如果在类里面的方法 中使用super() 相当于 super(当前类,self)
# super(当前类,self)是标准写法 super()是语法糖
# super(当前类,self)是python旧版本的语法 python3.x以后会自动推论
Box的fn方法 400
通过 s u p e r ( ) . _ _ i n i t _ _ ( ) super().\_\_init\_\_() super().__init__() 调用父类构造函数,以确保父类的构造函数被正确调用和初始化。
class Box:
def __init__(self,width,height):
self.width=width
self.height=height
class Box2(Box):
def __init__(self,width,height,color):
#继承父类的构造函数,
super(Box2,self).__init__(width,height)
#对象调用Box的super()方法,传入父类的参数width,height
# super().__init__(width,height)
self.color=color
b2=Box2(10,20,"red")
print(b2.color)
print(b2.width)
red
10