我的Python学习日记(八):Class 类

我的Python学习日记


DateLog
2023.12.05完成编写

8. Class 类

Python是一种面向对象的编程(Object-Oriented Programming, OOP),所以在Python中创建一个类和对象是很方便的

8.1 面向对象编程

面向对象编程是一种计算机编程范式,它基于对象的概念,其中对象是程序中的基本单元,并且这些对象可以通过定义类(Class)来创建。每个类可以包含数据与数据相关的方法。OOP 的设计理念是将程序的数据和操作数据的方法封装在一个单元中,这个单元就是对象。

OOP有以下几个核心概念:

  1. 类(Class)
    类是一种用户定义的数据类型,用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。
  2. 对象(Object)
    对象是类的实例,包含类定义的属性(数据成员)和方法(成员函数)。
    • 方法:类中定义的函数。
    • 数据成员:数据成员包括类变量和实例变量,用于处理类及其实例对象的相关数据。数据成员定义了类的属性。
      • 类变量:通常定义在类之中,函数之外,是类中所有实例化对象共享的,通常用于表示该类的所有实例共有的属性或状态。
      • 实例变量:在类的声明中用变量表示的属性,每个对象实例都有自己的一组实例变量,用self修饰,可以在整个类的方法中访问
    • 局部变量:在方法中定义的变量,作用范围限定在当前方法内。
  3. 封装(Encapsulation)
    封装是将类的实现细节隐藏起来,只暴露必要的接口,将对象内部的状态保护起来,只能通过类的方法进行访问和修改
    • 私有成员:使用私有成员(通常在属性名前加上双下划线__)可以限制外部直接访问
  4. 继承(Inheritance)
    继承允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以重用父类的代码,并可以在其基础上进行扩展或修改,即子类是父类的一种特例。

8.2 类的定义与对象

定义格式如下:

class myclass:
    var1 = value  # 类变量
    def func1():  # 方法(函数)
        函数体

类对象
类对象支持两种操作:属性引用和实例化
实例化是创建一个类的实例,即类的具体对象
属性引用和其他引用一致,即A.B形式

class myclass:
    def greet(self):
        return 'Hello World!'

s = myclass() # 实例化,这里s就是类的一个实例
print(s.greet())  # 属性引用

8.3 类的方法

类的方法定义也是使用def关键字,一般有实例方法静态方法类方法特殊方法四种。

8.3.1 实例方法

实例方法是最常见的方法类型。它们在类中被定义,并且至少有一个参数,通常被称为self,用于引用类的实例。

  • 一般来说不用装饰器的方法就是实例方法。
  • 实例方法可以访问和修改实例变量,也可以调用其他实例方法。
class myclass:
    def greet(self):
        print('Hello World!')

8.3.2 静态方法

静态方法与类相关联,但与实例无关,没有访问实例的权限,通常与类的状态无关,仅依赖于传入的参数。

  • 定义静态方法前要用@staticmethod装饰器
class myclass:
    @staticmethod
    def greet():
        print('Hello World!')

myclass.greet() # 可以跳过实例化直接调用
s = myclass  # 也可以实例化后再调用
s.greet()

8.3.3 类方法

类方法与整个类相关联,而不是与实例相关

  • 定义类方法前要用@classmethod装饰器
  • 类方法第一个参数通常被命名为 ‘cls’,用于引用类本身,而不是实例

8.3.4 特殊方法

特殊方法是以双下划线__开头和结尾的方法,在特定的操作发生时被调用,一般不是直接调用的

  1. __init__(self, ...):初始化方法,用于在创建对象时进行初始化操作,它在对象被创建时自动调用
  2. __str__(self):用于返回对象的字符串表示,在使用str()print()打印一个对象时,会自动调用对象的__str__方法
    • class myclass:
          def __str__(self) -> str:
            return 'Hello World!'
      
      print(myclass()) # Hello World!
      
  3. __len__(self):用于返回对象的长度,通常与内置函数 len() 一起使用。

Python 中还有更多特殊方法,以后再进行补充

8.3.5 一个例程

class Employee:
    total_employees = 0

    def __init__(self, name, salary): # 特殊方法__init__
        self.name = name
        self.salary = salary
        Employee.total_employees += 1  # 每次创建一个实例就相当于录入一个员工,员工数量+1
        print(f"{self.name}'s information has been uploaded.")  # 每次创建一个实例输出一次

    def __str__(self):  # 特殊方法__str__
        return f"{self.name} - Salary: ${self.salary}" 

    def apply_raise(self, raise_percentage):  # 实例方法,加薪
        self.salary *= (1 + raise_percentage)
        print(f"{self.name}'s salary after raise: ${self.salary}")

    @classmethod
    def get_total_employees(cls):  # 类方法,获取类变量总员工数
        return cls.total_employees

    @staticmethod
    def is_high_salary(salary):  # 静态方法,无关实例
        return salary > 50000

# 创建员工实例
employee1 = Employee("Alice", 45000)
employee2 = Employee("Bob", 60000)

# 打印员工信息
print(employee1)
print(employee2)

# 调用实例方法,给员工加薪
employee1.apply_raise(0.1)  

# 调用类方法,获取总员工数
total_employees = Employee.get_total_employees()
print(f"Total employees: {total_employees}")

# 调用静态方法,判断是否为高薪水
is_high_salary = Employee.is_high_salary(employee1.salary)
print(f"Is {employee1.name}'s salary considered a high salary? {is_high_salary}")

8.4 封装

封装是指将某些属性或方法封装在一个类的内部,无法从外部访问,隐藏了某些实现的细节,可以防止外部代码无意中修改内部状态,提高了数据的安全性。

一般来说,将类内的属性和方法封装的方式是以双下划线__开头来命名:

  1. 私有属性:私有属性是类中用于存储数据的变量,只能在类的内部访问。在类的外部,我们不能直接访问私有属性。
  2. 私有方法:私有方法是类中定义的用于实现某些功能的函数,只能在类的内部调用。

此外还有一种以单下划线_开头的命名方法,这是一种约定,告诉其他开发者这类成员是受保护的,但这只是一种约定,并没有真正的访问控制。


8.5 继承

8.5.1 基本信息

类的继承的逻辑是:子类会继承父类的属性和方法,也可以根据需要进行修改或扩展,基本语法为:

class ParentClass:
    # 父类的属性和方法
class ChildClass:
    # 子类的属性和方法
class Animal: # 父类
    def __init__(self, name):
        self.name = name

    def make_sound(self):
        pass

class Dog(Animal): # 子类继承父类,并对父类的make_sound函数进行重写
    def make_sound(self):
        return "Woof!"

class Cat(Animal):
    def make_sound(self):
        return "Meow!"

# 创建 Animal 类的实例
animal = Animal("Generic Animal")
print(f"{animal.name} says: {animal.make_sound()}") # Generic Animal says: None (父类中的make_sound函数并没有返回值)
dog = Dog("DaHuang")# 创建 Dog 类的实例
print(f"{dog.name} says: {dog.make_sound()}")
Cat = Cat("MiMi") # 创建 Cat 类的实例
print(f"{cat.name} says: {cat.make_sound()}")

8.5.2 方法重写

在上面的例子中,子类Cat和Dog对父类的make_sound函数进行了重写,以满足子类的需要

如果想重新调用父类中的同名方法,可以使用super()方法来调用:

class Dog(Animal):
    def make_sound(self):
        return super().make_sound() + " Bark!"

super([class,...])函数一般在实例方法内部调用,而不是在类的实例化时调用


8.5.3 多继承

多继承是指一个类可以继承自多个父类的属性和方法:

class ParentClass1:
    # 父类1的属性和方法
class ParentClass2:
    # 父类2的属性和方法
class ChildClass(ParentClass1, ParentClass2):
    # 子类的属性和方法
  • 需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,则会从左至右搜索括号中的父类包含的方法
  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HIT-Zxy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值