python面向对象

一、类与实例

类是抽象的,约定了未来实例应该有的内容,是实例的模版

实例是具体的,有具体数据,调用类则生成实例,实例的内容依赖于类

python 复制代码
class People:
    def __init__(self,name):
        self.name = name
p = People("张三")
print(p.name)

二、魔法函数

复制代码
以双下划线开头和结尾的函数称为魔法函数
魔法函数不需要自己调用
__init__ 用于初始化self
__str__ 返回实例的字符串表示,自定义内容的字符串
__len__ 使用len函数 返回实例对应的长度:自定义返回的数值

__eq__ 使用 == 触发
__ne__ 使用 != 触发
__gt__ 使用>触发
__ge__ 使用>=触发
__lt__ 使用<触发
__le__ 使用<=触发

__add__  使用+触发
__sub__  使用—触发
__mul__  使用*触发
__truediv__ 使用/触发
__floordiv__ 使用//触发
__mod__ 使用%触发
__divmod__ 使用div(x,y)触发

例子如下:

python 复制代码
class MyClass:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name},{self.age}"

    def __len__(self):
        return len(self.name)

    def __gt__(self, other):
        return self.age > other.age

    def __ge__(self, other):
        return self.age >= other.age

    def __lt__(self, other):
        return self.age < other.age

    def __le__(self, other):
        return self.age <= other.age

    def __eq__(self, other):
        return self.age == other.age

    def __ne__(self, other):
        return self.age != other.age

    def __add__(self, other):
        return self.age + other.age

    def __sub__(self, other):
        return self.age - other.age

    def __mul__(self, other):
        return self.age * other.age

    def __truediv__(self, other):
        return self.age / other.age

    def __floordiv__(self, other):
        return self.age // other.age

    def __mod__(self, other):
        return self.age % other.age

    def __divmod__(self, other):
        return divmod(self.age, other.age)


s0 = MyClass("zs", 18)
print(s0)
print(len(s0))

s1 = MyClass("ls", 20)
print(s1 > s0, s1 >= s0, s1 < s0, s1 <= s0)
print(s0 == s1, s0 != s1)
print(s0 + s1, s0 - s1, s0 * s1, s0 / s1, s0 // s1, s0 % s1, divmod(s0, s1))

三、三大特性

(一)封装

将数据与操作用类进行封装,例子如下:

复制代码
数据 state color与操作 is_open change_state get_color set_color用类Light进行封装
python 复制代码
class Light:
    def __init__(self):
        self.state = False
        self.color = ["蓝色","红色","白色"]
        self.current = 0
    def is_open(self):
        return self.state
    def change_state(self):
        self.state = not self.state
    def get_color(self):
        return self.color[self.current]
    def set_color(self):
        self.current += 1
        if self.current == len(self.color):
            self.current = 0
l0 = Light()
print(l0.is_open())
l0.change_state()
print(l0.is_open())

(二)继承

单继承

继承使用关键字classsuper()来实现,一个类可以继承另一个类的属性和方法,被继承的类称为父类或基类,继承的类称为子类或派生类。

子类可以访问父类的属性和方法,也可以添加自己的属性和方法。

例如,定义一个Person类作为父类,包含了nameage属性,以及walk()方法:

python 复制代码
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __str__(self):
        return f"姓名:{self.name},年纪:{self.age}"
    def walk(self):
        print("走路")

然后,定义一个SuperPerson类作为子类,继承了Person类的属性和方法,同时添加了自己的fly()方法以及skill属性:

python 复制代码
class SuperPerson(Person):
    def __init__(self,name,age,skill):
        # 继承父类的属性,super()是固定格式
        super().__init__(name,age)
        self.skill = skill
    def __str__(self):
        return f"{super().__str__()},技能:{self.skill}"
    def fly(self):
        print("会飞")

现在,创建一个Student对象,并调用继承自父类的walk()方法和子类的fly()方法:

python 复制代码
sp1 = SuperPerson("ljr",18,"变绿")
print(sp1)
sp1.walk()
sp1.fly()

通过继承,子类可以复用父类的代码,避免重复编写相同的属性和方法。

多继承

多继承是指一个类可以同时继承多个父类的特性和方法。多继承的语法非常简单,只需要在定义类时在类名后面添加括号,括号中写上要继承的所有父类的名称,用逗号隔开即可。

python 复制代码
class MoveAble:
    def __init__(self, speed):
        self.speed = speed

    def move(self):
        print(f"i can move, my speed is {self.speed}")

    def __str__(self):
        return "我是移动类"


class SpeakAble:
    def __init__(self, language):
        self.language = language

    def speak(self):
        print(f"i can speak {self.language}")

    def __str__(self):
        return "我是说话类"


class AttackAble:
    def __init__(self, skill):
        self.skill = skill

    def attack(self):
        print(f"使用{self.skill}发起攻击")

    def __str__(self):
        return "我是攻击类"


class Person(MoveAble, SpeakAble):
    def __init__(self, name, speed, language):
        # super().__init__()  会执行第一个父类
        # super().__init__(speed)

        # 通过类名表名 需要初始化哪个父类  必须传入self
        MoveAble.__init__(self, speed)
        SpeakAble.__init__(self, language)

        self.name = name

    def show(self):
        print(f"my name is {self.name}")

    def __str__(self):
        return "我是人类"


p0 = Person("小张", 50, "汉语")
p0.show()
p0.move()
p0.speak()


class ATM(Person, AttackAble):
    def __init__(self, name, speed, language, skill):
        Person.__init__(self, name, speed, language)
        AttackAble.__init__(self, skill)

    def __str__(self):
        return f"我是奥特曼类"


atm0 = ATM("赛罗", 1000, "光之语言", "赛罗光线")
atm0.show()
atm0.move()
atm0.speak()
atm0.attack()

print(atm0)

# 多继承 mro: method(方法)  retrieval(检索)  order(顺序)
# Python3 使用广度优先
print(ATM.mro())

(三)多态

多态是面向对象编程中的一个概念,它表示同一种操作可以作用于不同的对象,产生不同的结果。简单来说,多态就是一个接口(方法)具有多种实现方式。

在Python中,多态是通过方法重写(override)和方法重载(overload)实现的。

方法重写是指子类重新定义了父类中已经存在的方法,使得子类可以根据自己的需求对方法进行不同的实现。

方法重载是指在一个类中定义了多个同名但参数不同的方法,可以根据不同的参数类型和数量来调用不同的方法。

以下是一个使用多态的示例:

python 复制代码
class Animal:
    def sound(self):
        pass

class Dog(Animal):
    def sound(self):
        print("Woof!")

class Cat(Animal):
    def sound(self):
        print("Meow!")

def make_sound(animal):
    animal.sound()

dog = Dog()
cat = Cat()

make_sound(dog)  # 输出:Woof!
make_sound(cat)  # 输出:Meow!

在上面的例子中,我们定义了一个Animal父类,以及DogCat子类,它们都重写了父类的sound()方法。然后,我们定义了一个make_sound()函数,接受一个Animal对象作为参数,并调用其sound()方法。当我们传入Dog对象时,会调用Dog子类的sound()方法,输出狗叫声;当我们传入Cat对象时,会调用Cat子类的sound()方法,输出猫叫声。这就是多态的体现,相同的方法名可以根据不同的对象产生不同的结果。

多态提高了代码的灵活性和可扩展性,使得我们可以通过统一的接口实现不同的功能。

四、抽象类

抽象类是一个特殊的类,内部可以编写抽象方法,也可编写普通实例方法,抽象类不能直接实例化。抽象类子类必须实现抽象类中的抽象方法。

python 复制代码
from abc import ABC, abstractmethod


class Animal(ABC):

    @abstractmethod
    def walk(self):
        pass

    def eat(self):
        print(f"可以吃")


class Dog(Animal):

    def walk(self):
        print("摇摇尾巴")


dog = Dog()
dog.walk()
dog.eat()

五、实例属性与实例方法

实例属性是定义在类的实例对象上的属性。它们属于实例对象本身,并且每个实例对象都有自己的一份独立的属性。实例属性可以在类的方法中使用,也可以通过实例对象来访问和修改。

以下是定义实例属性的示例:

python 复制代码
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person1 = Person("Alice", 25)
person2 = Person("Bob", 30)

print(person1.name)  # 输出: Alice
print(person2.age)  # 输出: 30

person1.age = 26  # 修改实例属性
print(person1.age)  # 输出: 26

实例方法是绑定到实例对象上的方法。实例方法可以访问实例对象的属性,并且可以在方法内部对属性进行操作。实例方法可以在类的实例对象上调用。

以下是定义实例方法的示例:

python 复制代码
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def greet(self):
        print(f"Hello, my name is {self.name}!")

person = Person("Alice", 25)
person.greet()  # 输出: Hello, my name is Alice!

在上述示例中,greet方法是一个实例方法,它可以访问实例对象的属性name。在调用greet方法时,会自动将实例对象作为self参数传递给方法。通过self.name可以访问实例对象的name属性并输出。

六、类属性与类方法

类属性是定义在类上的属性,它属于整个类而不是类的实例对象。类属性在所有实例对象之间共享,并且可以通过类名或实例对象来访问。

类方法是定义在类上的方法,它可以通过类名或实例对象来调用。类方法的第一个参数通常被命名为cls,用于表示当前类对象。

以下是定义类属性和类方法的示例:

python 复制代码
class Person:
    count = 0  # 类属性

    def __init__(self, name):
        self.name = name
        Person.count += 1  # 访问类属性并进行修改

    @classmethod
    def get_count(cls):
        return cls.count  # 访问类属性

person1 = Person("Alice")
person2 = Person("Bob")

print(Person.get_count())  # 输出: 2

person3 = Person("Charlie")
print(person3.get_count())  # 输出: 3

在上述示例中,count是一个类属性,它记录了创建的Person实例对象的数量。在__init__方法中,每创建一个实例对象,都会通过Person.count对类属性进行修改。

get_count是一个类方法,通过使用装饰器@classmethod来定义。在类方法中,我们可以访问类属性count

类方法可以通过类名或实例对象来调用。通过Person.get_count()可以获得类方法的返回值,通过person3.get_count()也可以获得同样的结果。

需要注意的是,类方法无法访问实例属性,但可以通过参数传递实例对象来访问实例属性。

七、静态方法

静态方法是定义在类中的方法,它不与类的实例对象进行交互,也不与类属性进行交互。静态方法可以通过类名或实例对象来调用,但它不会自动接收任何参数。

以下是定义静态方法的示例:

python 复制代码
class MathUtils:
    @staticmethod
    def add(x, y):
        return x + y

    @staticmethod
    def multiply(x, y):
        return x * y

print(MathUtils.add(3, 5))  # 输出: 8
print(MathUtils.multiply(3, 5))  # 输出: 15

在上述示例中,addmultiply都是静态方法,通过使用装饰器@staticmethod来定义。静态方法可以直接通过类名来调用,无需先创建实例对象。静态方法内部可以访问其他静态方法或静态属性,但无法访问实例方法或实例属性。

静态方法通常用于执行与类相关但不依赖于实例对象的操作。它们可以提高代码的可读性和可维护性,因为它们清楚地表明它们不依赖于实例状态。

相关推荐
Yhame.43 分钟前
深入理解 Java 中的 ArrayList 和 List:泛型与动态数组
java·开发语言
Dovir多多1 小时前
Python数据处理——re库与pydantic的使用总结与实战,处理采集到的思科ASA防火墙设备信息
网络·python·计算机网络·安全·网络安全·数据分析
mazo_command3 小时前
【MATLAB课设五子棋教程】(附源码)
开发语言·matlab
IT猿手3 小时前
多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码
开发语言·人工智能·算法·机器学习·matlab
青春男大3 小时前
java栈--数据结构
java·开发语言·数据结构·学习·eclipse
88号技师3 小时前
几款性能优秀的差分进化算法DE(SaDE、JADE,SHADE,LSHADE、LSHADE_SPACMA、LSHADE_EpSin)-附Matlab免费代码
开发语言·人工智能·算法·matlab·优化算法
Zer0_on3 小时前
数据结构栈和队列
c语言·开发语言·数据结构
一只小bit3 小时前
数据结构之栈,队列,树
c语言·开发语言·数据结构·c++
沐霜枫叶3 小时前
解决pycharm无法识别miniconda
ide·python·pycharm
一个没有本领的人4 小时前
win11+matlab2021a配置C-COT
c语言·开发语言·matlab·目标跟踪