OOP基本特性

面向对象编程(Object-Oriented Programming,简称OOP)是一种通过组织对象来设计程序的编程方法。

Python天生就是面向对象的模块化编程。

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

1、封装

  • 封装是指将对象的属性和方法包装在一起,对外隐藏实现细节,只提供必要的接口给外部访问。

  • 在Python中,通过__init__方法初始化属性,并通过方法来操作这些属性。

  • __开头的属性或方法是私有的,在子类和类外部无法直接使用

  • 可使用“私有”属性和“公有”方法控制外部访问。

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('泰迪', 20)
print(dog.get_name()) 
dog.set_name('哈士奇') 
# print(dog._name)  # 私有属性不能直接访问,需要通过方法间接访问
print(dog._Dog__name)  # 私有属性不能直接访问,需要通过方法间接访问

2 、继承/派生

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

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

2.1基础概念

继承/派生

        继承是从已有的类中派生出新的类,新类具有原类的数据属性和行为,并能扩展新的能力。

        派生类就是从一个已有类中衍生出新类,在新的类上可以添加新的属性和行为

继承/派生的作用

        用继承派生机制,可以将一些共有功能加在基类中。实现代码的共享。

        在不改变基类的代码的基础上改变原有类的功能

继承/派生名词:

        基类(base class)/超类(super class)/父类(father class)

        派生类(derived class)/子类(child class)

2.2实现


# 继承是面向对象编程的重要概念,它是指一个类可以从另一个类继承其属性和方法,
# 并可以根据需要对其进行扩展。继承可以使得代码更加灵活、更加易于维护。

class Dog:
    def f1(self):
        print("f1方法")
    def f2(self):
        print("f2方法")

class Cat(Dog):  # Cat继承了Dog
    def f3(self):
        print("f3方法")

cat = Cat()
cat.f1()
cat.f2()
cat.f3()

#Cat类继承了Dog类,Cat类可以直接访问Dog类的方法,也可以添加自己的方法。
#继承的好处是可以重用代码,提高代码的复用性,减少代码的冗余度。

3、多态

  • 多态是指同一个方法在不同对象上具有不同的行为。

  • 通过多态,可以使得不同类型的对象以相同的接口表现出不同的行为。

  • 多态的实现通常通过继承和方法重写来实现。

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!"

4、重写

重写是面向对象编程的重要概念,它是指子类可以重新定义父类的方法,

使得子类对象在调用父类的方法时,会调用子类的方法。

4.1 对象转字符串重写

对象转字符串函数重写方法

str() 函数的重载方法:

  def __str__(self)

        如果没有 __str__(self) 方法,则返回repr(obj)函数结果代替

str/repr函数重写示例

 
class MyNumber:
     """此类用于定义一个自定义的类,用于演示str/repr函数重写"""
 ​
     def __init__(self, value):
         """构造函数,初始化MyNumber对象"""
         self.data = value
 ​
     def __str__(self):
         """转换为普通字符串"""
         return "%s" % self.data
 ​
 ​
 n1 = MyNumber("一只猫")
 n2 = MyNumber("一只狗")
 print("str(n2) ===>", str(n2))

4.2 内建函数重写

  • __abs__ abs(obj) 函数调用

  • __len__ len(obj) 函数调用

  • __reversed__ reversed(obj) 函数调用

  • __round__ round(obj) 函数调用

内建函数 重写示例

 file : len_overwrite.py
 class MyList:
     def __init__(self, iterable=()):
         self.data = [x for x in iterable]
 ​
     def __repr_(self):
         return "MyList(%s)" % self.data
 ​
     def __len__(self):
         print("__len__(self) 被调用!")
         return len(self.data)
 ​
     def __abs__(self):
         print("__len__(self) 被调用!")
         return MyList((abs(x) for x in self.data))
 ​
 ​
 myl = MyList([1, -2, 3, -4])
 print(myl.data)
 print(len(myl))
 print(abs(myl).data)

4.3 运算符重载

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

  • 运算符重载的作用

    • 让自定义类的实例像内建对象一样进行运算符操作

    • 让程序简洁易读

    • 对自定义对象将运算符赋予新的运算规则

  • 运算符重载说明:

    • 运算符重载方法的参数已经有固定的含义,不建议改变原有的意义

方法名运算符和表达式说明
__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
 rhs (right hand side) 右手边
  • 二元运算符重载方法格式:

     def __xxx__(self, other):
         ....
  • 算术运算符重载示例

     
class MyNumber:
     """此类用于定义一个自定义的类,用于演示运算符重载"""
 ​
     def __init__(self, value):
         """构造函数,初始化MyNumber对象"""
         self.data = value
 ​
     def __str__(self):
         """转换为表达式字符串"""
         return "MyNumber(%d)" % self.data
 ​
     def __add__(self, rhs):
         """加号运算符重载"""
         print("__add__ is called")
         return MyNumber(self.data + rhs.data)
 ​
     def __sub__(self, rhs):
         """减号运算符重载"""
         print("__sub__ is called")
         return MyNumber(self.data - rhs.data)
 ​
 ​
 n1 = MyNumber(100)
 n2 = MyNumber(200)
 print(n1 + n2)
 n = n1 - n2
 print(n.data)

5、super函数

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

5.1基本使用

  • 在子类方法中使用 super().add() 调用父类中已被覆盖的方法

  • 使用 super(Child, obj).myMethod() 用于子类对象调用父类已被覆盖的方法

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
class Parent:  # 定义父类
    def myMethod(self):
        print('调用父类方法')


class Child(Parent):        # 定义子类
    def myMethod(self):
        print('调用子类方法')


c = Child()                 # 子类实例
c.myMethod()                # 子类调用重写方法
super(Child, c).myMethod()  # 用子类对象调用父类已被覆盖的方法

5.2super().__init__()

通过 super().\_\_init\_\_() 调用父类构造函数,以确保父类的构造函数被正确调用和初始化。

class Parent:
    def __init__(self):
        print("Parent class constructor called")
        self.parent_attribute = "I am a parent attribute"


class Child(Parent):
    def __init__(self):
        super().__init__()
        print("Child class constructor called")
        self.child_attribute = "I am a child attribute"


# 创建一个 Child 类的实例
child_instance = Child()
print(child_instance.parent_attribute)

# 输出
# Parent class constructor called
# Child class constructor called

为什么使用 super().__init__()

  • 代码重用:避免在子类中重复父类的初始化代码。

  • 正确初始化:确保父类的初始化逻辑(如设置属性、分配资源等)被执行。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值