风雨同行 发表于 2025-4-1 06:08:31

31天Python入门——第17天:初识面向对象

https://i-blog.csdnimg.cn/blog_migrate/50175a8cb7fcd6935a4b84f6906c219e.gif#pic_center
         你好,我是安然无虞。    

https://i-blog.csdnimg.cn/blog_migrate/f758308c2fce20f249517b6f3f77f331.gif#pic_center
面向对象编程

1. 什么是面向对象

面向对象编程是一种编程思想,它将现实世界的概念和关系映射到代码中.
在面向对象编程中,我们通过创建对象来表示现实世界中的事物,并通过定义对象的属性和方法来描述它们的状态和举动.
面向对象编程强调了代码的模块化、封装、抽象、继承和多态等概念.
比方, 在现实世界中我们须要去记录一名学生的基本信息, 如果利用文本来记录: 比方
有一名学生叫张三, 来自北京, 性别男. 这样可以轻松记录一名学生的信息.
但是利用如下表格, 结构会更加的清晰.
姓名张三年龄20籍贯北京性别男 在现实世界中我们须要去记录一辆车的基本信息, 须要用到如下表格:
品牌型号排量车架号 上述都表格都可以很清晰的描述学生和车辆的基本信息.
表格相当于是 一个蓝图或者模板. 每个学生都可以拿着这个表格, 填写自己对应的信息, 在程序中, 上面的表格就相当于是一个类, 通过这个类可以创建多个学生对象.
2. 类(class)

类和对象是面向对象编程的核心概念.
类是一个抽象的概念,用于描述对象的属性(数据)和方法(举动).
对象则是类的具体实例,表示一个具体的实体.
类(class)
类是一种模板或蓝图,用于创建对象.它定义了对象的属性和方法,描述了对象的状态和举动.类通过定义一组相干的属性和方法来封装数据和利用,从而提供了一种构造和管理代码的方式.
Python 中的统统对象都有各自的范例,比如:
整数对象   的类型是   int
字符串对象 的类型是   str
列表对象   的类型是   list
元组对象   的类型是   tuple
字典对象   的类型是   dict
Python 的内置函数type可以查看对象的范例:
>>> type(12)
<class 'int'>    # 整数类型
>>> type('12')
<class 'str'>    # 字符类型
>>> type()
<class 'list'>   # 列表类型
>>> type((1,2))
<class 'tuple'># 元组类型
>>> type({1:2})
<class 'dict'>   # 字典类型
我们掌握了这些内置的数据范例,通常就可以开发Python程序了.
但是当我们要开发的软件系统 更加复杂的时候,尤其是系统里面的对象 和现实世界的对象 存在对应关系的时候,如果只能用这些内置范例,就会感觉很不方便.
比如,我们的程序要表示一个 奔驰汽车 这样的对象范例,属性有:品牌,国家,价格.
如果只用Python的内置范例,各人想想怎么表示.
固然,我们可以定义一个字典范例的对象,比如:
benzCar = {
    'brand'   : '奔驰',
    'country' : '德国',
    'price'   : 300000
}
如果这个汽车对象还须要有自己特定的举动,比如 按喇叭会发出嘟嘟的声音。那又该怎么定义呢?
有人说,可以定义一个函数对象作为它的属性,像这样:
defpressHorn():
    print('嘟嘟~~~~~~')

benzCar = {
    'brand'   : '奔驰',
    'country' : '德国',
    'price'   : 300000,
    'pressHorn' : pressHorn # 字典对象的值可以是一个函数对象
}

# 我可以这样执行它的行为
benzCar['pressHorn']()
好像也可以.
但是这里 benzCar 更像是一个具体的对象,并不是一种 对象范例.
而且 这个 benzCar 汽车的 举动的定义 ,要在外面定义一个函数, 然后benzCar字典的内部去引用它,这样也比力麻烦.
为了办理这样的普遍问题,Python语言可以让我们 自己定义对象范例.
Python中自定义对象范例,就是 定义一个类 , 类 就是 范例 的意思.
比如 : 奔驰汽车, 可以这样定义:
利用 class 关键字定义一个类.类名通常利用大写字母开头,遵循大驼峰命名规范.
class BenzCar:   
    brand   = '奔驰'# 品牌属性
    country = '德国'# 产地属性

    @staticmethod
    def pressHorn():
      print('嘟嘟~~~~~~')
定义一个类 用关键字 class 背面加 类的名称.
类名的规范 和 变量命名规范一样。 通常我们会把类名 首字母大写, 这里定义的类名就是 BenzCar
下面定义的 brand, country 都是 BenzCar 类的 属性.
这种属性被称为类属性
如果我们要得到属性的值可以这样用 类名.属性名 的方式,如下
print(BenzCar.brand)
而 pressHorn 则是该范例的一个 方法.
请留意上面的 @staticmethod 的修饰, 说明这是该类的一个 静态方法
要调用实行该类的静态方法,像这样就可以了:
BenzCar.pressHorn()
类的属性
类的属性是与类相干联的数据,用于描述对象的特征或状态.
类的属性可以通过类名或对象访问.类属性在类级别上定义,被全部类的实例共享.
类属性的定义现实上就是写在类中的变量. (成员变量) - 留意不是实例属性哦
class Student:

name = '张三'
age = 0
在上面的示例中, Student类定义了2个类属性, name和age,它被全部Student类的实例共享. 类属性可以通过类名或者实例对象访问.
class Student:
name = '张三'
age = 18

# 类属性可以通过**类名或者实例对象**访问
print(Student.name)
print(Student.age)

print("-----------------------------")

stu = Student()
print(stu.name)
print(stu.age)
类的方法
类的方法是与类相干联的函数,用于定义对象的举动.方法在类中定义,并通过对象调用.方法可以访问和利用对象的属性.
class Student:

name = '张三'
age = 0
   def introduce(self):    print(f'各人好, 我的名字叫{self.name}, 本年{self.age}岁')   def study(self):   print(f'{self.name}正在努力学习.')   stu = Student()stu.introduce()stu.study() 以上示例在Student类中定义了2个方法, introduce和study. 用于定义对象的2个举动: 自我介绍和学习.
上述示例中方法中第一个形参是self的方法叫做实例方法. 类属性可以通过实例对象self来访问.
3. 类的实例

Python中 类 是 某种对象的范例.
比如 int 是 整数对象的范例, str是字符串对象的范例, list是 列表对象的范例.
我们把一个个具体的 对象称为 该范例的 实例,
比如,我们可以说
数字对象 3 是 int 范例的的实例,具有int范例的特征
字符串对象 ‘abc’ 是 str 范例的实例,具有str范例的特性(比如可以实行str的全部方法,比如 find, split等)
列表对象 是 list 范例的的实例,具有list范例的特性(比如可以实行list的全部方法,比如 reverse,append等)
同样的,我们自定义的类,也可以产生该类的实例对象. 每个实例对象就是该类的一个实例,具有该类的统统特征.
要产生一个类的实例对象,只须要 在类名背面加上括号,就可以了,就会返回一个该类的实例对象.
比如:
car1 = BenzCar()

car1 变量就对应了一个 BenzCar 范例 的实例对象,具有 BenzCar 类的统统属性和方法.各人可以实行下面的代码试试。
class BenzCar:      brand   = '奔驰'      country = '德国'      @staticmethod    def pressHorn():         print('嘟嘟~~~~~~')car1 = BenzCar()

       print(car1.brand) car1.pressHorn() 同样,我们也可以用 type 函数查看 car1 这个实例的范例,如下所示:
>>> type(car1)
<class '__main__.BenzCar'>
说明 car1 是 __main__ 模块里面定义的 BenzCar 范例.
各人一定要搞清晰 类 和 实例 的关系.
比如 :
人 就是 一个 类, 而 关羽、张飞 就是 人 这个类的 具体实例.
狗 也是 一个 类, 而 你们家的阿黄 和 隔壁家的旺财 就是狗 这个类的 具体实例.
Python中 定义一个范例 就是描述 这些范例的实例的 公共特征. 背面根据这个类创建的实例 都具有这个类的 特征,就是 具体什么 属性、方法.
在面向对象编程中,类的对象(Class Object)是类的具体实例, 以是类的对象也叫做实例对象.类定义了对象的属性和方法,而对象是类的实体,具有自己的属性值和对类中方法的访问权限.
实例属性和实例方法
刚才我们定义的类里面的属性都是 类属性 ,里面的方法都是类的 静态方法 .
全部BenzCar类的实例对象,其 品牌名 brand ,对应的类属性应该是相同的.
就是说下面这样的两个实例:
car1 = BenzCar()

   car2 = BenzCar() car1 和 car2 的 brand属性 都是一样的 值, 都是字符串 ‘奔驰’
很好理解,因为品牌这样的属性 对于全部的 奔驰车都是一样的,都是 ‘奔驰’.
类属性 是类的共同特征属性.
但是有些属性,比如颜色、发动机编号 是每一辆奔驰车 都不同的.
以是,在我们定义的 类BenzCar 里面, 颜色、发动机编号 是 不应该 作为类属性的.
每个实例独有的属性,称之为 类的实例属性
实例属性通常是在类的 初始化方法 init 里面定义的.
比如:
class BenzCar:   
    brand   = '奔驰'
    country = '德国'

    @staticmethod
    def pressHorn():
      print('嘟嘟~~~~~~')

    # 初始化方法, 注意前后各有两个下划线
    def __init__(self):
      self.color='red'      # 颜色
      self.engineSN = '837873398' # 发动机编号
上面的初始化方法 __init__ ,就创建了两个实例属性 color 和 engineSN。
为什么 __init__ 方法 叫初始化方法呢?
解释器在实行 像下面这样的 实例化类对象 的代码时,
car1 = BenzCar()

首先,解释器会 在内存中 创建一个该类 的 实例对象;
然后,解释器会查看这个类是否有 __init__方法,如果有,就会去调用它.
__init__ 是 创建好实例后 立即就要 实行 的方法,以是称之为初始化方法.
通常我们会在__init__方法里面 实行一些初始化的动作,紧张就是创建该实例的 实例属性.
__init__ 方法的第一个参数是 self, 它 是干什么用的呢?
刚才说了, 解释器实行实例化代码,会先在内存中创建该类实例对象,然后调用类 的__init__方法.
调用 __init__方法时,就将实例对象 转达给 self参数.
self 参数变量 指向的 就是 实例对象 自己, 以是下面的代码就是创建该实例的属性color 和 engineSN 了
self.color='red'         # 颜色
self.engineSN = '8378738398' # 发动机编号
类的静态方法要在方法定义 上面加上 @staticmethod 的修饰.
而 类的 实例方法 不须要任何修饰.
通常类的实例方法,都是要 访问类的实例属性的. 包括: 创建、修改、删除 类的实例属性.
因为 实例方法 就是要利用 实例独有的属性,否则不利用任何实例属性的话,就应该定义为 类方法.
比如 __init__ 初始化方法,就是一个实例方法,它通常要创建一些实例属性.
而 pressHorn 方法是类的静态方法, 静态方法是不能访问实例属性的.
偶然候,实例属性的取值,不是固定写在初始化方法的代码里面.
比如这里,每辆车的颜色、发动机号都是不同的,我们应该作为参数传进去.
以是修改代码为这样:
class BenzCar:   
    brand   = '奔驰'
    country = '德国'

    @staticmethod
    def pressHorn():
      print('嘟嘟~~~~~~')

    def __init__(self,color,engineSN):
      self.color=color   # 颜色
      self.engineSN = engineSN # 发动机编号
这样我们在创建实例的时候,就可以根据须要指定不同的实例属性了,比如:
car1 = BenzCar('白色','24503425527866')
car2 = BenzCar('黑色','34598423586877')
print(car1.color)
print(car2.color)
print(car1.engineSN)
print(car2.engineSN)
虽然定义的时候, init 方法 有3个参数 : self,color,engineSN
但是我们这样调用 BenzCar() 实例化的时候, 只须要传入背面两个参数即可,
因为self 参数 须要传入实例对象自己,解释器会自动帮我们传入.
其它的 实例方法也是这样, 比如我们定义一个 修改车身颜色的方法 changeColor:
class BenzCar:   
    brand   = '奔驰'
    country = '德国'

    @staticmethod
    def pressHorn():
      print('嘟嘟~~~~~~')

    def __init__(self,color,engineSN):
      self.color=color   # 颜色
      self.engineSN = engineSN # 发动机编号

    def changeColor(self,newColor):
      self.color = newColor

car1 = BenzCar('白色','24503425527866')      
car1.changeColor('黑色')

print (car1.color)
调用 changeColor方法的时候,只须要传入参数 newColor 对应新的颜色即可.
不须要我们传入self参数,self 参数是实例对象自己,解释器会自动帮我们传入.
留意: 如果你的实例属性名称 和 静态属性(类属性) 重复了 ,通过类实例访问该属性,访问的是实例属性通过类名访问该属性,访问的是类属性.
比如:
class Car:
    brand = '奔驰'
    name = 'Car'

    def __init__(self):
      # 可以通过实例访问到类属性
      print(self.brand)

      # 定义实例属性和类属性重名
      self.name = 'benz car'

c1 = Car()

print(f'通过实例名访问name:{c1.name}')
print(f'通过类名访问name:{Car.name}')
一旦创建了 和类属性同名的 实例属性,通过实例访问的就是实例属性了
实例方法是指定义在类中的方法, 它可以访问和利用对象的实例属性, 并且在调用时会自动传入对象自身(通常用 self 来表示)作为第一个参数.
实例方法是与类的实例(对象)关联的, 并且可以访问和修改对象的状态.
利用实例方法时, 须要先创建类的实例(对象), 然后通过对象调用方法, 在调用实例方法时, 不须要手动传入 self 参数, Python会自动将对象自己转达给方法.
关于self


[*]在实例方法中, 第一个参数通常是 self, 表示对象自身. 定义实例方法时, 必须将 self 作为方法的第一个参数.通过 self, 方法可以访问对象的属性和其他方法.
[*]在创建类的实例(对象)时, Python会自动转达 self 参数给实例方法, 不须要手动传入.当调用对象的方法时, 无需显式转达 self, Python会自动将对象自己转达给方法.
[*]在实例方法内部, 可以通过 self 来访问对象的属性和方法.比方, self.attribute 可以访问对象的属性, self.method() 可以调用对象的其他方法
4. 对象的初始化

__init__ 是Python中一个特别的方法, 用于初始化对象的属性.它是在创建对象时自动调用的构造方法, 也叫做邪术方法.
在类的定义中, __init__ 方法用于初始化对象的属性.通常, 在创建对象时须要对对象的属性进行初始化利用, 比如设置默认值或接收外部传入的参数.
__init__ 方法的命名是固定的, 必须利用双下划线 __ 前缀和后缀.在调用类创建对象时, Python会自动调用类的 __init__ 方法来初始化对象的属性.
留意: __init__方法只能返回None, 不能有其他返回值.
实例属性
实例属性是指定义在类的实例(对象)中的属性, 每个对象都有自己独立的实例属性.实例属性用于存储对象的状态和数据, 并且在类的实例化过程中被赋予特定的值.
在Python中, 实例属性通常是在类的构造方法 __init__ 中利用 self 关键字定义的.(类的实例属性在类外(或者说是__init__方法外定义的实例属性)也有定义的环境)
每个实例属性都是一个对象独有的变量, 不同的对象之间互不干扰.
class Student:
    def __init__(self, name, age):
      self.name = name
      self.age = age

    def introduce(self):
      print(f"大家好, 我的名字叫{self.name}, 今年{self.age}岁")
      self.study_course('英语')

    def study_course(self, course):
      print(f"{self.name}正在努力学习{course}")


stu1 = Student("李四", 18)
stu1.introduce()
stu1.study_course("english")

stu2 = Student("张三", 20)
stu2.introduce()
stu2.study_course("maths")
实例属性和类属性总结

[*] 定义位置:

[*]实例属性:实例属性是定义在类的方法中(通常是在构造函数 __init__ 中)通过 self 关键字定义的, 每个实例(对象)都有自己的一份实例属性.
[*]类属性:类属性是定义在类的方法之外的属性, 直接在类的内部定义的, 属于整个类, 全部实例共享同一份类属性.

[*] 存储位置:

[*] 实例属性:每个实例(对象)都有自己独立的实例属性, 存储在对象中.
[*] 类属性:类属性属于整个类, 存储在类中.

[*] 值的独立性:

[*]实例属性:不同实例的同名实例属性是相互独立的, 一个实例的实例属性修改不会影响其他实例.
[*]类属性:全部实例共享同一份类属性, 但是通过一个实例修改类属性时, 这个修改不会影响其他实例的类属性.类属性是属于类的, 而不是属于实例的, 因此每个实例都拥有独立的类属性副本, 互不影响.

[*] 访问方式:

[*] 实例属性:通过对象访问, 利用表达式 对象名.属性名.
[*] 类属性:可以通过类名访问, 也可以通过对象访问.利用表达式 类名.属性名 或 对象名.属性名.

5. __str__

__str__是Python中的特别方法(邪术方法), 用于定义类的实例对象的字符串表示.
当我们利用print函数或str()函数打印一个类的实例对象时, 现实上是调用了该对象的__str__方法来获取其字符串表示.
如果在类中定义了__str__方法, 那么当我们打印该类的实例时, 会输出__str__方法返回的字符串.这对于自定义类的字符串表示非常有用, 可以让我们以更加直观和可读的方式展示对象的内容.
紧张用途包括:

[*]打印:当你利用print函数打印一个对象时, 现实上是调用该对象的__str__方法来获取其字符串表示, 从而以更直观和易读的方式表现对象的信息.
[*]字符串转换:当你利用str()函数来将一个对象转换为字符串时, 同样会调用该对象的__str__方法, 以获得其字符串表示.
[*]字符串格式化:在字符串格式化时, 如果包含了对象, Python会自动调用对象的__str__方法, 以便获取对象的字符串表示.
class Student:

    # 类属性
    gender = '男'

    def __init__(self, name, age):
      # 实例属性
      self.name = name
      self.age = age

    def introduce(self):
      print(f"大家好, 我的名字叫{self.name}, 今年{self.age}岁")
      self.study_course()

    def study_course(self, course="英语"):
      print(f"我正在努力学习{course}")

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

# 1. 打印
stu = Student("李四", 18)
print(stu)
# 2. 字符串转换
stu_string1 = str(stu)
print(stu_string1)
# 3. 字符串格式化
stu_string2 = f'{stu}'
print(stu_string2)

# 输出结果:
学生: 李四, 18, 男
学生: 李四, 18, 男
学生: 李四, 18, 男
6. 类之间的关系

继承关系

真实世界中,范例之间 可能存在 范围 包含关系.
比如:人 这个范例 和 亚洲人 这个范例.
人 是包括了 亚洲人 的。 如果 某人 是一个 亚洲人,那么它必定是一个 人.
这种关系,编程语言中称之为 继承关系.
比如上面的例子, 亚洲人 这个类 就 继承 了 人 这个类.
通常我们把被继承的类称之为 父类 或者叫 基类.
把继承类称之为 子类 或者 派生类.
同样的,以车为例, 上面我们定义了奔驰车 这个类, 我们还可以定义两个 子类: 奔驰2016 和 奔驰2018 对应两种不同款的奔驰车.
如下所示:
class BenzCar:   
    brand   = '奔驰'
    country = '德国'

    @staticmethod
    def pressHorn():
      print('嘟嘟~~~~~~')

    def __init__(self,color,engineSN):
      self.color=color# 颜色
      self.engineSN = engineSN # 发动机编号

    def changeColor(self,newColor):
      self.color = newColor

class Benz2016(BenzCar):
    price   = 580000
    model   = 'Benz2016'   

class Benz2018(BenzCar):
    price   = 880000
    model   = 'Benz2018'
各人可以发现定义子类的时候,必须指定它的父类是什么.
指定的方法就是在类名的背面的括号里写上父类的名字.
各人留意: 子类会自动拥有父类的统统属性和方法
为什么? 因为一个子类的实例对象 ,必定也是一个父类的实例对象. 固然须要拥有父类的统统属性和方法.
就像 一个亚洲人 固然 拥有一个 人 所应该具有的统统特性.
比如,实行下面的代码:
car1 = Benz2016('red','234234545622')   
car2 = Benz2018('blue','111135545988')   

print (car1.brand)
print (car1.country)
car1.changeColor('black')

print (car2.brand)
print (car2.country)
car2.pressHorn()
输出结果如下:
奔驰
德国
奔驰
德国
嘟嘟~~~~~~
一个子类在继承父类的统统特性的底子上,可以有自己的属性和方法.
比如:
class Benz2018(BenzCar):
    price   = 880000
    model   = 'Benz2018'   

    def __init__(self,color,engineSN,weight):
      # 先调用父类的初始化方法
      BenzCar.__init__(self,color,engineSN)
      self.weight = weight # 车的重量
      self.oilweight = 0# 油的重量

    # 加油
    def fillOil(self, oilAdded):
      self.oilweight +=oilAdded
      self.weight    +=oilAdded
这里 子类 Benz2018 ,新增了两个 类属性
价格: price
型号: model
新增了两个实例属性
整车重量:weight
油的重量:oilweight
新增了一个实例方法 fillOil , 对应 加油这个举动.
这个举动会导致 实例属性 weight 和 oilweight 变化,以是必须是 实例方法.
这样定义好了以后, 就可以创建该类的实例,并访问其新的方法和属性了.
car2 = Benz2018('blue','111135545988',1500)   
print (car2.oilweight)
print (car2.weight)
car2.fillOil(50)
print (car2.oilweight)
print (car2.weight)
   要特别留意的是, 子类的初始化方法里面,如果有一部分的初始化代码和父类的初始化相同(通常都是这样),须要显式的 调用父类的初始化方法 __init__
而且要传入相应的参数, 像上面那样,然后可以加上自己的特有的初始化代码. 如下所示:
def __init__(self,color,engineSN,weight):
    # 先调用父类的初始化方法
    BenzCar.__init__(self,color,engineSN)
    self.weight = weight
    self.oilweight = 0
如果子类 没有 自己的初始化方法,实例化子类对象时,解释器会自动调用父类初始化方法,如下:
class Rect:
    def __init__(self):
      print('初始化 rect')

class Squre(Rect):
    pass

s = Squre()
运行结果,会打印出 ‘初始化 rect’
但是,如果子类 有自己 的初始化方法,实例化子类对象时,解释器就不会自动化调用父类的初始化方法,如下
class Rect:
    def __init__(self):
      print('初始化 rect')

class Square(Rect):
    def __init__(self):
      print('初始化 square')

s = Squre()
运行结果只会打印 初始化 square.
调用父类的方法,除了直接用父类的名字 BenzCar, 还可以利用 函数 super()
像这样:
def __init__(self,color,engineSN,weight):
    # 同样是调用父类的初始化方法
    super().__init__(color, engineSN)
    self.weight = weight
    self.oilweight = 0
这样利用的时候,方法参数中 不须要加上 self 参数.
利用 super 的好处之一就是:子类中调用父类的方法,不须要 显式指定 父类的名字. 代码的可维护性更好.
想象一下,如果 BenzCar 有很多子类,如果哪一天 BenzCar 类改了名字,接纳 super 这样的写法,就不须要修改子类的代码了.
留意 super不但仅可以调用父类的初始化方法,也可以调用父类的其他方法.
一个子类,同时还可以是另一个类的父类,
比如 亚洲人 可以是 人 的子类, 同时可以是 中国人 的父类.
因为一个中国人,一定是一个亚洲人, 固然也一定是一个 人.
同样的,上面的车的例子, 我们还可以定义 奔驰2018混淆动力 作为 奔驰2018 的 子类.
定义的语法还是一样的:
class Benz2018Hybrid(Benz2018):
    model = 'Benz2018Hybrid'
    price = 980000

    def __init__(self,color,engineSN,weight):
      Benz2018.__init__(self,color,engineSN,weight)
同样,类 Benz2018Hybrid 也会拥有其父类 Benz2018 的统统属性和方法,自然也包括 父类的父类 BenzCar 的统统属性和方法
car2 = Benz2018Hybrid('blue','111135545988',1500)   
print (car2.oilweight)
print (car2.weight)
car2.fillOil(50)
print (car2.oilweight)
print (car2.weight)
组合关系

除了上面的继承关系, 类之间还有一种常见的组合关系.
所谓组合关系,就是一个类实例的属性里面包含别的一个类实例.
比如:
class BenzCar:   
    brand   = '奔驰'
    country = '德国'


    def __init__(self,color,engineSN):
      self.color=color   # 颜色
      self.engineSN = engineSN # 发动机编号
这样的定义,类 BenzCar 中
brand 属性就是一个字符串对象 奔驰
country 属性就是一个字符串对象 德国
而该类的实例对象中,就包含了 两个属性 color 和 engineSN, 都是字符串对象
我们可以说 该类由 一些字符串对象 组合 而成.
甚至还可以包含 我们自己定义的类的实例,比如:
# 轮胎
class Tire:   
    def __init__(self,size,createDate):
      self.size=size# 尺寸
      self.createDate = createDate # 出厂日期

class BenzCar:   
    brand   = '奔驰'
    country = '德国'

    def __init__(self,color,engineSN,tires):
      self.color=color# 颜色
      self.engineSN = engineSN # 发动机编号
      self.tires   =tires

# 创建4个轮胎实例对象
tires =
car = BenzCar('red','234342342342566',tires)
上面的例子里,奔驰汽车对象就 包含 了4个轮胎 Tire 对象.
我们可以说奔驰汽车对象是由 4个轮胎对象 组合 而成,形成了对象的组合关系.
对象的 属性 变量 生存了 组合它的那些对象.
组合关系,可以通过上层对象的属性一步的访问到内部对象的属性
比如,我们可以通过 BenzCar 对象 访问其内部的轮胎对象
print(car.tires.size)
Python解释器对这个表达式 car.tires.size 是从左到右依次实行的,如下所示:
car.tires   # BenzCar实例的tires属性,得到一个列表,里面是四个 Tire 实例对象

car.tires   # 得到BenzCar实例的tires属性列表里面的第1个Tire 实例对象

car.tires.size# 得到BenzCar实例的tires属性列表里面的第1个Tire 实例对象的size属性
7. 补充练习

"""
创建一个简单的学生管理系统,包含以下功能:

定义一个Student类,包含以下属性:学号(number),姓名(name),年龄(age),性别(gender)和成绩(score)。

实现类的初始化方法__init__,用于初始化学生的属性。

实现类的__str__方法,用于返回学生信息的字符串表示,格式为:学号:[学号],姓名:[姓名],年龄:[年龄],性别:[性别],成绩:[成绩]。

定义一个学生管理类StudentManager,用于管理学生信息。该类应该包含以下功能:

添加学生:能够添加一个学生的信息到学生列表中。
显示所有学生:能够打印出所有学生的信息。
因为之前我们已经做过了类似的管理系统, 所以这里就不再做很复杂的功能, 只做两个小功能达到练习的目的即可.
"""

# 学生类
class Student:

    def __init__(self, number, name, age, gender, score):
      self.number = number
      self.name = name
      self.age = age
      self.gender = gender
      self.score = score

    def __str__(self):
      return f"学号:[{self.number}],姓名:[{self.name}],年龄:[{self.age}],性别:[{self.gender}],成绩:[{self.score}]"


# 学生管理类
class StudentManager:

    def __init__(self):
      self.stu_list = []

    def add_stu(self, student):
      self.stu_list.append(student)
      print(f'添加学生{student.name}成功')

    def show_all_stu(self):
      for stu in self.stu_list:
            print(stu)


def main():
    # 主流程
    student_manager = StudentManager()
    print('欢迎进入学生管理系统')
    while True:
      print('1: 添加学生')
      print('2: 展示所有学生')
      print('0: 退出系统')
      choice = int(input("请输入操作编号: "))
      if choice == 1:
            number = input('请输入学生学号')
            name = input('请输入学生姓名')
            age = input('请输入学生年龄')
            gender = input('请输入学生性别')
            score = input('请输入学生分数')
            student = Student(number, name, age, gender, score)
            student_manager.add_stu(student)
      elif choice == 2:
            student_manager.show_all_stu()
      elif choice == 0:
            print(f"退出学生管理系统")
            break
      else:
            print('您输入的指令是无效指令')


if __name__ == '__main__':
    main()
         遇见安然遇见你,不负代码不负卿。             谢谢老铁的时间,咱们下篇再见~    
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 31天Python入门——第17天:初识面向对象