python基础之--面相对象--OOP基本特性

python基础之–面相对象–OOP基本特性

文章目录

  • python基础之--面相对象--OOP基本特性
  • 一,OOP基本特性
      • 1.1 封装
      • 1.2 继承/派生
        • 1.2.1 基础概念
      • 1.2.3继承实现
    • 1.3多态
  • 1.4对象对成员的操作(补充)
  • 1.5私有属性
  • 1.6重写
    • 魔术方法
  • 二,super函数
    • 2.1基本使用
    • 2.2 super().\__init__()


一,OOP基本特性

OOP的四大基本特性是封装继承多态抽象

1.1 封装

  • 封装是指将对象的属性和方法包装在一起,对外隐藏实现细节,只提供必要的接口给外部访问。
  • 在Python中,通过__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岁,调用了吃东西方法

1.2 继承/派生

儿子继承了父亲,父亲派生了儿子~

Python中所有的类最终都继承自内置的object类。

1.2.1 基础概念
  • 继承/派生
    • 继承是从已有的类中派生出新的类,新类具有原类的数据属性和行为,并能扩展新的能力。
    • 派生类就是从一个已有类中衍生出新类,在新的类上可以添加新的属性和行为
  • 继承/派生的作用
    • 用继承派生机制,可以将一些共有功能加在基类中。实现代码的共享。
    • 在不改变基类的代码的基础上改变原有类的功能
  • 继承/派生名词:
    • 基类(base class)/超类(super class)/父类(father class)
    • 派生类(derived class)/子类(child class)

1.2.3继承实现

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

1.3多态

  • 多态是指同一个方法在不同对象上具有不同的行为。
  • 通过多态,可以使得不同类型的对象以相同的接口表现出不同的行为。
  • 多态的实现通常通过继承和方法重写来实现。
#多态
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

1.4对象对成员的操作(补充)

#对象对成员的操作
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

1.5私有属性

#私有属性
# __属性名
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

1.6重写

魔术方法

  • 运算符重载是指让自定义的类生成的对象(实例)能够使用运算符进行操作

  • 运算符重载的作用

    • 让自定义类的实例像内建对象一样进行运算符操作
    • 让程序简洁易读
    • 对自定义对象将运算符赋予新的运算规则
  • 运算符重载说明:
    运算符重载方法的参数已经有固定的含义,不建议改变原有的意义

方法名 运算符和表达式 说明
__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函数

super() 函数是用于调用父类(超类)的一个方法

2.1基本使用

  • 在子类方法中使用 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

2.2 super()._init_()

通过 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

你可能感兴趣的:(python,开发语言,人工智能)