1.什么是面向对象编程OOP
Python的面向对象编程
(Object-Oriented Programming,简称OOP)是一种编程范式,它使用"对象"来设计应用程序和计算机程序。这些对象由数据和能够操作这些数据的方法组成。面向对象编程的主要目标是提高软件的可重用性、可维护性和灵活性。在Python中,面向对象编程具有以下几个核心概念:
-
类(Class):
- 类是创建对象的模板或蓝图。它定义了一组属性(称为字段或变量),以及操作这些数据的方法。一个类可以包括基本的数据属性(静态的信息片段),以及能够对数据执行特定功能的方法。
-
对象(Object):
- 对象是类的实例。如果类是蓝图,对象就是根据这个蓝图构建的房子。每个对象都拥有类定义的字段和方法的具体实例。即便两个对象来自同一个类,它们也可以拥有不同的数据属性。
-
封装(Encapsulation):
- 封装是面向对象编程的一个主要特点,指的是将对象的数据(属性)和代码(方法)捆绑在一起,形成一个独立的单元。在封装的概念中,类通常会防止外部代码直接访问内部数据结构,而是通过方法(称为getter和setter)来操作数据,这提供了更好的数据控制和更容易的维护。
-
继承(Inheritance):
- 继承允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。子类重用父类的代码可以减少冗余,而且子类可以扩展或修改从父类继承的行为,这提高了代码的可用性和可扩展性。
-
多态(Polymorphism):
- 多态是指同一个接口支持不同的底层形态(数据类型)。在Python中,多态表现为可以通过相同的接口调用不同类的方法,具体调用哪个方法取决于调用方法的对象。比如,不同的类可能都定义了一个相同的方法名,但是每个类的该方法的具体实现可能不同。
-
抽象(Abstraction):
- 抽象是简化复杂的现实问题的方法,它通常用于隐藏复杂度,只显示最相关的细节。在Python中,可以使用抽象类来定义不能直接实例化的类,这些抽象类意在专门为其他类提供基本的、通用的功能模板,具体实现则留给继承了抽象类的子类。
通过使用这些OOP原则,Python程序员能够创建可读性强、易于扩展和维护的应用程序。
2.常用方法及代码实现
① 类和对象
创建一个类,实例化一个对象并调用类中定义的方法。
# 常见的类和对象
class Foo: # 定义一个Foo类,包含两个方法Bar和Hello
def Bar(self): # Bar是Foo类的一个方法,不接受除 self(指向类实例本身的引用)之外的任何参数。当Bar方法调用时它会打印字符串"Cheney"
print('Cheney')
def Hello(self,name): # Hello是Foo类的另一个方法,接受一个参数name以及隐式的self参数。该方法打印一句格式化字符串,其中包含传入的name参数
print("我的名字是:{}".format(name))
# 根据类Foo创建一个实例对象obj
obj=Foo() # 变量obj按照Foo类的定义生成
obj.Bar() # obj调用类中的Bar方法,会直接打印出"Cheney"
obj.Hello('CheneyCliff') # obj调用类中的Hello方法,并将CheneyCliff参数传给Hello方法,最终打印出一个格式化字符串
② 封装
下面的代码定义了一个名为 Foo
的类,并且在这个类中封装了两个属性:name
和 age
。封装是面向对象编程的一大特性,它主要用于将数据(属性)和与数据相关的方法绑定在一起,形成一个独立的实体(对象),这样的封装可以提高代码的复用性和安全性。
# 面向对象三大特性
# 一、封装的含义顾名思义就是将内容封装到某个地方,以后再去调用被封装在该处的内容
class Foo:
def __init__(self,name,age): # __init__ 方法是一个特殊的方法,称为类的构造器。当创建类的新实例时,这个方法会被自动调用,它的主要任务是初始化对象的属性
# self.name 和 self.age 是对象的两个属性,分别被赋予方法参数 name 和 age 的值
self.name=name
self.age=age
# 第1步:将内容封装到某处
Figure1=Foo('Gatsby',20)
Figure2=Foo('Daisy',19)
# 第2步:通过对象直接从某处调用被封装的内容
print('Figure1的name为:%s'%Figure1.name)
print('Figure2的age为:%d'%Figure2.age)
③ 调用封装的内容
#第二步:2、通过self间接调用被封装的内容
class Foo:
def __init__(self,name,age): # 初始化对象属性
self.name=name
self.age=age
def detail(self): # 定义一个detial方法
print(self.name)
print(self.age)
obj1=Foo('Gatsby',20) # 实例化一个对象
obj1.detail() # 调用detail方法
④ 继承
继承是面向对象三大特性之一(另外两个是封装和多态)。继承允许一个类(称为子类)继承另一个类(称为父类或基类)的属性和方法。这样做的主要好处是代码重用,可以将通用的代码放在一个父类中,通过继承机制在多个子类中复用这些代码。
# 二、继承、面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容
class Animal: # 定义一个父类Animal
# 定义父类的四个方法
def eat(self):
print("%s 吃"%self.name) # 使用self.name来访问和输出动物的名称
def drink(self):
print("%s 喝"%self.name)
def shit(self):
print("%s 拉"%self.name)
def pee(self):
print("%s 撒"%self.name)
# 定义子类
class Dog(Animal): # Dog类继承自Animal类
def __init__(self,name):
self.name=name # 初始化了狗的名字,这对于调用父类中定义的方法(如eat、drink等)是必需的
self.breed='狗'
def cry(self): # 定义一个Dog类的特定行为
print("汪汪汪")
class Cat(Animal): # Cat类继承自Animal类
def __init__(self,name):
self.name=name
self.breed='猫'
def cry(self):
print("喵喵喵")
dog=Dog("Gatsby家的小狗") # 传入狗的名称,初始化对象
dog.eat() # 调用两次eat方法
dog.eat()
dog.cry()
cat=Cat('Daisy家的小猫') # 传入猫的名称,初始化对象
cat.drink()
⑤ 类的继承机制
在Python中,类的继承机制允许多重继承,这意味着一个类可以同时继承多个父类。这与Java和C#等其他面向对象的编程语言不同,后者仅支持单一继承,但可以通过接口来实现多继承的某些效果。在Python中,多继承引入了寻找方法和属性的顺序问题,即当一个类继承自多个父类时,Python2.X需要一个明确的规则来决定从哪个父类中寻找方法或属性,这就涉及到深度优先和广度优先的搜索策略。
在Python 2中,有经典类和新式类之分。Python 3中,所有类默认都是新式类(即使不显式继承自 object
)。'即使不显式'通常用于描述某些操作或行为在没有明确指定的情况下依然会发生的情况,这种说法帮助简化代码和提高编程效率,但同时它也要求开发者理解默认行为,以避免意外的错误。
在Python 3中,类的继承和方法解析遵循C3线性化 算法。C3线性化是一种特定的算法,用于解决在具有多重继承的类体系中确定方法解析顺序的问题。这个算法确保任何类都会在其父类之前被检查,同时也保持了父类的顺序。这意味着,Python 3中不再单纯使用传统的深度优先或广度优先策略来解析方法调用。
# 1.Python的类可以继承多个类,Java和C#中则只能继承一个类
# 2.Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是深度优先和广度优先
# 当类是经典类时,多继承情况下会按照深度优先方式查找
# 当类是新式类时,多继承情况下会按照广度优先方式查找
# 经典类(Python2.X):
class C1:
pass
class C2(C1):
pass
# 新式类(Python3.X)
# 在Python3.x中,所有的类默认继承自内置的 object 类,即使你没有在类定义中显式地指明继承自 object
# 这意味着即使不显式地声明,所有类都将继承object类的所有方法和属性,这包括基本的方法如 __str__()、__repr__() 和 __new__() 等
class N1(object):
pass
class N2(N1):
pass
下面展示的是一个多重继承的例子。
class D:
def bar(self):
print("D.bar")
class C(D):
def bar(self):
print("C.bar")
class B(D):
def bar(self):
print("B.bar")
# A是一个多重继承的类,继承自B和C。因此,它具有从这两个类继承而来的所有属性和方法
class A(B,C):
def bar(self):
print("A.bar")
# Python查找并执行bar()方法的顺序是根据类A的方法解析顺序(MRO)。由于A自己定义了bar()方法,因此调用的就是这个方法。
a=A()
a.bar()
# 在Python中,可以使用类的mro()方法来查看方法解析顺序
print(A.mro())
⑥ 多态
多态是面向对象编程(OOP)中的一个核心概念,它允许在不同类的对象上以共同的方式调用相同的方法,而具体执行什么方法则取决于调用方法的对象的实际数据类型。这使得编程更加灵活,并增强了代码的可扩展性和可维护性。多态字面意思是"多种形态",在编程中,它允许使用者以统一的接口处理不同类型的对象。
在下面的例子中,Animal
类定义了一个 speak
方法,Dog
和 Cat
类继承自 Animal
并重写了 speak
方法。函数 animal_sound
接受一个 Animal
类型的对象,并调用它的 speak
方法。当传递 Dog
和 Cat
对象时,尽管 animal_sound
函数的参数类型是 Animal
,它依然调用了实际类型对应的方法。
# 三.多态
class Animal:
def speak(self):
print("Some sound")
class Dog(Animal):
def speak(self):
print("Woof woof")
class Cat(Animal):
def speak(self):
print("Meow meow")
def animal_sound(animal):
animal.speak() # 调用传入对象的speak方法
# 创建Dog和Cat的实例对象
dog = Dog()
cat = Cat()
# 传递不同的对象
animal_sound(dog) # 输出: Woof woof
animal_sound(cat) # 输出: Meow meow
多态是实现开闭原则的关键部分,即软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。这使得在不更改现有代码的情况下,用户可以添加新功能,使系统易于扩展和维护。
以上内容总结自网络,如有帮助欢迎转发,我们下次再见!