一、面向对象
1.1 面向过程&面向对象
目前主流的编程范式分为面向过程和面向对象:
面向过程就是先分析出解决问题的步骤,再把步骤拆成一个个方法,是没有对象去调用的,通过一个个方法的执行解决问题(亲力亲为)
面向过程的代表语言:
C语言:C语言是一种典型的面向过程编程语言,它提供了丰富的过程式编程特性,如函数、变量和流程控制语句
汇编语言:汇编语言是与计算机硬件紧密相关的低级编程语言,它主要面向过程,程序员需要手动管理内存和寄存器等资源
面向对象就是将编程当成是一个事物(对象),对外界来说,事物是直接使用的,不用去管内部的情况,而编程就是设置事物能做什么事情(偷懒,找别人/工具替我做)
面向对象的代表语言:
Java:Java是一种广泛使用的面向对象编程语言,它将所有的代码组织成类和对象,支持封装、继承和多态等面向对象的概念
C++:C++是一种混合了面向对象编程和过程式编程的语言。它扩展了C语言,引入了类和对象的概念,同时保留了C语言的功能
Python:Python是一种多范式的编程语言,但它也支持面向对象编程,允许程序员定义类、创建对象,并通过对象间的消息传递来实现功能
Ruby:Ruby是一种面向对象的动态脚本语言,它强调简洁和灵活的语法,并采用了纯粹的面向对象模型
选择哪种编程范式取决于具体的问题和项目的需求
对于小型、简单的任务,面向过程可能更加直观和高效。然而,对于大型、复杂的项目,面向对象提供了更好的可维护性、可扩展性和代码复用性,因此通常是更好的选择。
1.2 举例子解释两种范式区别
用洗衣服这个例子来形象地解释面向对象和面向过程两种不同的编程范式:
面向过程(洗衣服用手洗):
想象一下,你决定用手洗衣服。面向过程的方式就像是你按照一系列步骤来完成这个任务:
准备阶段:你收集所有要洗的衣服,找到洗衣盆、洗衣粉和清水
浸泡阶段:你将衣服放入洗衣盆中,加入适量的水和洗衣粉,让衣服浸泡一段时间
搓洗阶段:你开始用手搓洗衣服,重点搓洗污渍较重的地方
冲洗阶段:你倒掉脏水,用清水冲洗衣服,直到没有洗衣粉泡沫为止
拧干阶段:你用手拧干衣服,或者找一块干净的布吸走多余的水分
晾干阶段:你将衣服挂在晾衣绳上,等待它们自然晾干
在这个过程中,你(程序员)是主体,你亲自执行每一步操作(函数调用)。这些步骤是线性的,一步一步来,没有太多的复用性和扩展性。如果下次你要洗更多的衣服或者换一种洗衣粉,你可能需要调整整个流程
面向对象(洗衣服用洗衣机洗):
现在,想象一下你有一台洗衣机。面向对象的方式就像是你使用洗衣机这个“对象”来完成洗衣服的任务:
准备阶段:你收集所有要洗的衣服,找到洗衣机和洗衣粉
设置阶段:你将衣服放入洗衣机,加入适量的洗衣粉,并选择合适的洗涤程序(比如“日常洗”、“快速洗”或“强力洗”)
启动阶段:你按下洗衣机的启动按钮,洗衣机开始自动执行洗涤、漂洗和脱水等步骤
完成阶段:洗衣机完成洗涤后,你取出衣服,挂在晾衣绳上晾干
在这个过程中,洗衣机(对象)是主体,它封装了洗涤、漂洗和脱水等步骤(方法),并提供了不同的洗涤程序(多态性)。你只需要告诉洗衣机你要做什么(发送消息),它就会自动完成整个过程。如果下次你要洗更多的衣服或者换一种洗衣粉,你只需要调整洗衣机的设置,而不需要改变整个流程。
通过这两个例子,我们可以看到面向对象编程相比面向过程编程具有更高的复用性、灵活性和扩展性
洗衣机(对象)可以很容易地被复用和扩展,以适应不同的洗涤需求,而手洗衣服(面向过程)则需要每次都从头开始,并且难以复用和扩展
二、类和对象
类:就是对一系列具有相同属性和行为的事物的统称,不是真实存在的事物,是一个抽象的概念
对象:是类的具体实现,是类创建出来的真实存在的事物,面向对象思想的核心
在开发中,先有类,再有对象
2.1 类的三要素
1. 类名
2. 属性:对象的特征描述,用来说明是什么样子的
3. 方法:对象具有的功能(行为),用来说明能够做什么
eg:
类名:人类
属性:身高、体重、年龄
方法:走路、说话、学习Python
类名:洗衣机类
属性:长度、宽度、高度
方法:洗衣服
2.2 定义类
基本格式:
class 类名: # 类名必须符合标识符规定,同时遵循大驼峰命名法,见名知意
代码块
eg:
# 洗衣机类
class Washer:
height = 800 # 类属性:就是类所拥有的属性
# 查看类属性:类名.属性名
print(Washer.height) # 输出结果:800
# 新增类属性:类名.属性名 = 值
Washer.width = 450
print(Washer.width) # 输出结果:450
2.3 创建对象
创建对象的过程也叫做实例化对象
实例化对象的基本格式: 对象名 = 类名()
eg:实例化一个洗衣机对象
# 洗衣机类
class Washer:
height = 800 # 类属性:就是类所拥有的属性
# 查看类属性:类名.属性名
print(Washer.height) # 输出结果:800
# 新增类属性:类名.属性名 = 值
Washer.width = 450
print(Washer.width) # 输出结果:450
# 实例化一个洗衣机对象
wa = Washer()
print(wa) # 显示的对象在内存中的地址
# 第二次实例化
wa2 = Washer()
print(wa2)
# 内存地址不一样,说明是不同的对象,可以实例化多个对象
2.4 实例方法&实例属性
由对象调用,至少有一个self 参数,执行实例方法的时候,自动将调用该方法的对象赋值给self
eg:
class Washer:
height = 800 # 类属性
def wash(self): # self参数是类中的实例方法必须具备的,self表示当前调用该方法的对象
print("我会洗衣服")
# 实例化对象
wa = Washer()
# 对象调用类中的方法
wa.wash()
# 输出结果:我会洗衣服
# self代表对象本身,当对象调用实例方法时,
# Python会自动将对象本身的引用作为参数,传递到实例方法的第一个参数self里面
实例属性(Instance Attributes)
实例属性是与类的某个具体实例相关联的变量。它们通常在对象被创建时(即在__init__方法中)被初始化
格式:
class MyClass:
def __init__(self, value):
self.instance_attribute = value # 实例属性
eg:
class Person:
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age # 实例属性
# 创建实例
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)
# 访问实例属性
print(person1.name) # 输出: Alice
print(person2.age) # 输出: 25
实例属性:在 __init__ 方法中定义,通过 self 关键字关联到实例对象
实例方法(Instance Methods)
实例方法是定义在类中,但需要通过类的实例来调用的函数。它们可以访问和修改实例属性
格式:
class MyClass:
def instance_method(self, arg1, arg2):
# 方法体
pass
eg:
class Person:
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age # 实例属性
def greet(self): # 实例方法
print(f"Hello, my name is {self.name}.")
def increment_age(self): # 实例方法
self.age += 1
# 创建实例
person1 = Person("Alice", 30)
# 调用实例方法
person1.greet() # 输出: Hello, my name is Alice.
person1.increment_age()
print(person1.age) # 输出: 31
实例方法:第一个参数是 self,通过实例对象来调用,可以访问和修改实例属性
eg:下面是一个简单的Python类Person,它包含两个实例属性(name和age)以及两个实例方法(greet和celebrate_birthday)
class Person:
def __init__(self, name, age):
# 实例属性
self.name = name # 每个人的名字不同
self.age = age # 每个人的年龄不同
def greet(self):
# 实例方法,用于打印问候语
print(f"Hello, my name is {self.name}!")
def celebrate_birthday(self):
# 实例方法,用于庆祝生日并更新年龄
print(f"Happy birthday, {self.name}! You are now {self.age + 1} years old.")
# 更新年龄(这里仅为了演示,实际中可能需要更复杂的逻辑)
self.age += 1
# 创建Person类的一个实例(对象)
alice = Person("Alice", 30)
# 访问实例属性
print(alice.name) # 输出: Alice
print(alice.age) # 输出: 30
# 调用实例方法
alice.greet() # 输出: Hello, my name is Alice!
# 再次调用实例方法,并观察年龄的变化
alice.celebrate_birthday() # 输出: Happy birthday, Alice! You are now 31 years old.
# 再次访问实例属性,确认年龄已经更新
print(alice.age) # 输出: 31
解释
实例属性:
self.name 和 self.age 是Person类的实例属性
当我们创建Person类的一个实例(例如alice)时,这些属性会被初始化为提供的值(在这个例子中是"Alice"和30)
实例方法:
greet 和 celebrate_birthday 是Person类的实例方法
它们通过self参数访问实例属性,并可以修改这些属性(如celebrate_birthday方法中做的那样)
要调用实例方法,我们需要先创建类的实例,然后通过该实例来调用方法(例如alice.greet())
2.4.1 实例属性和类属性的区别
类属性属于类,是公共的,大家都能访问到,实例属性属于对象的,是私有的,只能由对象名访问,不能由类名访问,实例属性只能由对象名访问,不能由类名访问
类属性:
- 定义:类属性是在类定义中直接定义的属性,或者在类的外部通过类名来赋值的属性
- 访问权限:类属性可以通过类名直接访问,也可以通过实例名访问
- 共享性:所有该类的实例共享同一个类属性
class MyClass:
class_attribute = "I am a class attribute"
print(MyClass.class_attribute) # 通过类名访问
obj = MyClass()
print(obj.class_attribute) # 通过实例名访问
实例属性:
- 定义:实例属性是在类的某个实例(对象)上定义的属性,通常是在类的初始化方法(
__init__
)中定义的 - 访问权限:实例属性只能通过实例名访问,不能通过类名直接访问(除非通过某种方式获得实例的引用)
- 私有性:虽然实例属性不是严格意义上的“私有”,但它们与特定的实例相关联,而不是与类本身相关联
class MyClass:
def __init__(self):
self.instance_attribute = "I am an instance attribute"
obj = MyClass()
print(obj.instance_attribute) # 通过实例名访问
# print(MyClass.instance_attribute) # 这会抛出 AttributeError,因为类本身没有这个属性
注意事项
1、访问控制:Python 并没有真正的私有属性或方法。虽然可以使用双下划线前缀(__)来模拟私有属性(这会导致名称重整),但这只是约定俗成的做法,仍然可以通过类的一些内部机制访问这些属性
2、共享与独立性:类属性是所有实例共享的,改变一个实例的类属性会影响到所有其他实例。而实例属性是独立的,改变一个实例的属性不会影响其他实例
eg:
class MyClass:
class_attribute = "Class attribute"
def __init__(self, value):
self.instance_attribute = value
# 创建两个实例
obj1 = MyClass("Instance 1")
obj2 = MyClass("Instance 2")
# 访问类属性
print(MyClass.class_attribute) # 输出: Class attribute
print(obj1.class_attribute) # 输出: Class attribute
print(obj2.class_attribute) # 输出: Class attribute
# 修改类属性
MyClass.class_attribute = "Modified class attribute"
print(obj1.class_attribute) # 输出: Modified class attribute
print(obj2.class_attribute) # 输出: Modified class attribute
# 访问实例属性
print(obj1.instance_attribute) # 输出: Instance 1
print(obj2.instance_attribute) # 输出: Instance 2
# 修改实例属性
obj1.instance_attribute = "Modified instance 1"
print(obj1.instance_attribute) # 输出: Modified instance 1
print(obj2.instance_attribute) # 输出: Instance 2 (未受影响)
今天的分享就到这里了,希望能帮助到大家~