面向对象编程中的类详解

        面向对象编程(OOP)是一种编程范式,是最有效的软件编写方法之一。主要通过类(Class)和对象(Object)来实现代码的重用和管理。在Python中,类和对象是实现OOP的基础。在面向对象的编程中,你编写表示现实世界中的事物和情景的类class,并基于这些类来创建对象object

1. 类的介绍与定义

        类是对一类对象的抽象,它定义了这类对象的属性和行为。使用类,我们几乎可以模拟任何东西 ,通过类,我们可以创建具有相同属性和行为的对象实例。类的定义通常包括属性(变量)和方法(函数)。

定义一个简单的类

以下是一个简单的Dog类的定义:

class Dog:
    # 模拟小狗的一次简单尝试
    def __init__(self, name, age):
        # 初始化属性name和age
        self.name = name
        self.age = age

    def sit(self):
        # 模拟小狗收到命令时坐下
        print(f"{self.name} is now sitting")

    def roll_over(self):
        # 模拟小狗收到命令时打滚
        print(f"{self.name} roll over!")
  • __init__方法:初始化方法,当创建对象时会自动调用。self参数是对当前对象的引用。
  • sitroll_over方法:类的方法定义了对象的行为。
  • 需要注意的是,“__init__”前后都是英文的两个下划线,前面两条下划线,init后面还是两条下划线。

2. 创建和使用实例

实例是根据类创建的对象,每个实例都有独立的属性和方法。

Dog类

# 根据类创建实例
my_dog = Dog('Willie', 6)
your_dog = Dog('Lucy', 3)

print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")
my_dog.sit()
my_dog.roll_over()

print(f"Your dog's name is {your_dog.name}.")
print(f"Your dog is {your_dog.age} years old.")
your_dog.sit()
your_dog.roll_over()

#输出结果为:
My dog's name is willie.
my dog is 6 years old.
willie is now sitting
willie roll over !
your dog's name is Lucy.
your dog is 3 years old.
Lucy is now sitting
Lucy roll over !

 Car类

class Car:
    def __init__(self, make, model, year):
        # 初始化描述汽车的属性
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        # 返回格式化的描述性信息
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()

    def read_odometer(self):
        # 打印汽车行驶里程的信息
        print(f"This car has {self.odometer_reading} miles on it.")

 

3.修改属性的值

现在我i们通过给Car类,添加一个新的属性"odometer_reading",并将其值设为0,定义一个名为read_odometer()的方法,这样我i们就能轻松知道汽车的行驶里程。

class Car:
    def __init__(self, make, model, year):
        # 初始化描述汽车的属性
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        # 返回格式化的描述性信息
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()

    def read_odometer(self):
        # 打印汽车行驶里程的信息
        print(f"This car has {self.odometer_reading} miles on it.")

    

一开始,汽车的行驶里程为0,但是出售时里程表为0的汽车不多,因此我们就得学会如何修改属性的值了。

修改属性的值有3种方法,分别是,直接通过实例修改,通过方法设置,以及通过方法递增。

直接修改属性的值

class Car:
    def __init__(self,make,model,year):
        '''初始化描述汽车的属性'''
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        '''返回格式的描述性信息'''
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()
    def read_odometer(self):
        '''打印一条指出汽车行驶里程的消息'''
        print(f"This car has {self.odometer_reading} miles on it.")
    
    
my_car = Car('audi','a4','2024')
print(my_car.get_descriptive_name())
my_car.odometer_reading = 23#直接通过实例修改属性的值
my_car.read_odometer()

 my_car.odometer_reading = 23#直接通过实例修改属性的值

通过创建的实例直接进行修改所需要的值

 通过方法修改属性的值

如果有一个替你更新属性的方法,你就无需访问属性了,可以将值直接传递给方法,由它在内部进行更新。

'''一次模拟汽车的简单尝试'''
class Car:
    def __init__(self,make,model,year):
        '''初始化描述汽车的属性'''
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        '''返回格式的描述性信息'''
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()
    def read_odometer(self):
        '''打印一条指出汽车行驶里程的消息'''
        print(f"This car has {self.odometer_reading} miles on it.")
    def update_odometer(self,mileage):
        self.odometer_reading = mileage#通过添加一个新的方法来更新里程表属性的值
    
my_car = Car('audi','a4','2024')
print(my_car.get_descriptive_name())
my_car.read_odometer()

 def update_odometer(self,mileage):
        self.odometer_reading = mileage

通过添加一个新的方法来更新里程表属性的值,只需将值传入该方法,自己更新值,即修改属性的值

 通过方法让属性的值递增

有时候需要将属性的值进行特定量的递增,而不是设置为全新的值。假设你买了一辆二手的车,从购买到登记期间增加了100英里的路程,下面这个方法就能够传递这个增量,并相应的更新里程表的读数。

class Car:
    def __init__(self,make,model,year):
        '''初始化描述汽车的属性'''
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        '''返回格式的描述性信息'''
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()
    def read_odometer(self):
        '''打印一条指出汽车行驶里程的消息'''
        print(f"This car has {self.odometer_reading} miles on it.")
  
    def increment_odometer(self,miles):
        '''让里程表增加指定的量'''
        self.odometer_reading += miles#通过方法让里程表属性的值递增
    
    
my_car = Car('audi','a4','2024')
print(my_car.get_descriptive_name())
my_car.read_odometer()

4.继承

        有时候我们需要创建一个新的类,而这个类包含既有的类的属性和方法,这个时候我们就可以使用继承。继承是创建子类的方式,子类可以继承父类的属性和方法,还可以扩展自己的属性和方法。

比如,我们想在Car汽车类下面创建一个电动车类,电动车继承了汽车的一些属性和方法。

子类的__init__方法

class ElectricCar(Car):
    # 子类所具有的独特属性
    def __init__(self, make, model, year):
        # 初始化父类属性
        super().__init__(make, model, year)
        self.battery_size = 40  # 添加电动车特有的属性:电池


    def describe_battery(self):
        # 打印电池容量的信息
        print(f"This car has a {self.battery_size}-kWh battery.")

 1.在既有的类上创建新类,通常要调用父类的__init__方法,这样将初始化父类的所有属性,从而让子类也可以使用这些属性。

2.super()是一个特殊的函数,让你能够调用父类的方法。

3.在创建子类时,父类必须包含在当前文件中,且位于子类的前面。

4.在创建子类时,要在括号后面加上父类,class ElectricCar(Car):

给子类定义属性和方法

class ElectricCar(Car):
    # 子类所具有的独特属性
    def __init__(self, make, model, year):
        # 初始化父类属性
        super().__init__(make, model, year)
        self.battery_size = 40  # 添加电动车特有的属性:电池

    def describe_battery(self):
        # 打印电池容量的信息
        print(f"This car has a {self.battery_size}-kWh battery.")

在新的子类中,添加了子类所独有的属性和方法:

1.self.battery_size = 40  # 添加电动车特有的属性:电池

2.def describe_battery(self):
        # 打印电池容量的信息
        print(f"This car has a {self.battery_size}-kWh battery.")

重写父类中的方法

有时候,父类中的一些方法并不能满座子类中的要求,可以对父类中的方法重写

class ElectricCar(Car):
    # 子类所具有的独特属性
    def __init__(self, make, model, year):
        # 初始化父类属性
        super().__init__(make, model, year)
        self.battery_size = 40  # 添加电动车特有的属性:电池

    def describe_battery(self):
        # 打印电池容量的信息
        print(f"This car has a {self.battery_size}-kWh battery.")
    def fill_gas_tank(self):
        '''电动车没有油箱'''
        print("This car doesn't have a gas tank!")

 这里我们假设父类中也有一个名为fill_gas_tank()的方法,Python将会自动忽略对父类中的fill_gas_tank方法,转而运行子类中的代码。在使用继承时,可以继承父类的“精华”,重写不需要的“糟粕”。

5.将实例用作属性

要将一个实例用作另一个类的属性,可以通过在一个类中包含另一个类的实例。这种方法称为“组合”。

class Battery:
    def __init__(self, battery_size=40):
        # 初始化电池容量属性
        self.battery_size = battery_size

    def describe_battery(self):
        # 打印电池容量的信息
        print(f"This car has a {self.battery_size}-kWh battery.")



class ElectricCar(Car):
    '''电动车的独特属性'''

    def __init__(self, make, model, year):
        # 初始化父类属性
        super().__init__(make, model, year)
        # 初始化电池属性,实例化Battery类
        self.battery = Battery()

    def describe_battery(self):
        # 使用Battery实例的方法
        self.battery.describe_battery()

1.class Battery这是一个新类,没有继承任何父类,形参battery_size=40默认值设置为40,

2.class ElectricCar类,添加了一个名为 self.battery = Battery()的新属性,该行代码表示让Python创建一个新的实例Battery,并将该实例赋值给属性 self.battery。

6.导入类

导入类的方法有很多种,module_name是你的模块的名字

从模块导入类

from module_name import ClassName

导入模块的所有类

from module_name import *

导入整个模块

import module_name

给类或模块指定别名

from module_name import ClassName as CN
import module_name as mn

各自的优缺点

  • 从模块导入类:明确指出使用的类,避免命名冲突。代码清晰,但需逐个导入。
  • 导入模块的所有类:简洁,但可能导致命名冲突,特别是在大项目中。
  • 导入整个模块:使用模块名调用类,明确来源,避免命名冲突,但代码较长。
  • 类或模块别名:简化名称,适用于名称较长的模块或类,代码简洁,但需确保别名具有可读性。

7.类的编程风格

类名应采用驼峰命名法,即类的名字中的每个单词首字母大写并且不使用下划线,而实例和模块名都采用单词小写,并且每个单词之间加下划线的格式,

驼峰命名法(CamelCase)是一种命名约定,主要用于编程中命名变量、函数和其他标识符。驼峰命名法的名称来源于单词在名称中间大写字母的使用,这些大写字母使得名称看起来像骆驼的驼峰。根据大写字母的位置不同,驼峰命名法分为以下两种:

  1. 小驼峰命名法(lowerCamelCase)

    • 第一个单词以小写字母开头,后续的每个单词的首字母大写。
    • 示例:myVariableNamegetUserInfo
  2. 大驼峰命名法(UpperCamelCase)

    • 每个单词的首字母都大写,包括第一个单词。
    • 示例:MyVariableNameGetUserInfo

驼峰命名法的使用有助于提高代码的可读性,使变量和函数名更具描述性,便于开发人员理解和维护代码。不同的编程语言和开发团队可能会有不同的命名规范,驼峰命名法是其中一种常见的规范。

相关推荐

  1. 面向对象编程详解

    2024-06-17 20:26:05       7 阅读
  2. Python面向对象编程

    2024-06-17 20:26:05       38 阅读
  3. Python,面向对象详解

    2024-06-17 20:26:05       5 阅读
  4. Python编程面向对象(二)—多态

    2024-06-17 20:26:05       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-17 20:26:05       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-17 20:26:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-17 20:26:05       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-17 20:26:05       20 阅读

热门阅读

  1. 【镜像制作】docker命令的参数解释及用法

    2024-06-17 20:26:05       7 阅读
  2. NSNumber转float或double类型避免小数点后补0

    2024-06-17 20:26:05       8 阅读
  3. 使用 Selenium 保持登录会话信息

    2024-06-17 20:26:05       7 阅读
  4. MySQL触发器基本结构

    2024-06-17 20:26:05       8 阅读
  5. jingxiang制作

    2024-06-17 20:26:05       6 阅读
  6. 使用Spring Boot设计对象存储系统

    2024-06-17 20:26:05       7 阅读
  7. 在php中的序列化与反序列化

    2024-06-17 20:26:05       10 阅读
  8. 谈吐的艺术

    2024-06-17 20:26:05       8 阅读
  9. Mariadb/MySQL挂了且重启失败

    2024-06-17 20:26:05       7 阅读
  10. 软设之白盒测试

    2024-06-17 20:26:05       6 阅读
  11. 时区设置函数【man 3 tzset】

    2024-06-17 20:26:05       5 阅读