在Python中,面向对象编程(OOP)是一种在编程中使用对象和类的编程范式。它旨在实现现实世界的实体,如继承,多态性,封装等。在编程中,OOP的主要概念是将数据和处理数据的函数绑定在一起作为一个单元,这样代码的其他部分就不能访问这些数据。
Python中的OOP概念
- 类
- 对象
- 继承
- 多态
- 封装
- 数据抽象
1. 类
类是对象的集合。类包含创建对象所依据的蓝图或原型。它是一个包含一些属性和方法的逻辑实体。
为了理解创建类的必要性,让我们考虑一个示例,假设您希望跟踪可能具有不同属性(如品种和年龄)的狗的数量。如果使用列表,则第一个元素可以是狗的品种,而第二个元素可以表示其年龄。假设有100只不同的狗,那么你怎么知道哪个元素应该是哪个?如果你想给这些狗添加其他属性呢?这缺乏组织性,这正是类的需要。
关于Python类的一些要点:
- 类由关键字class创建。
- 属性是属于类的变量。
- 属性始终是公共的,可以使用点(.)操作。例如:Myclass.Myattribute
类定义语法:
class ClassName:
# Statement-1
.
.
.
# Statement-N
在Python中创建空类
class Dog:
pass
在上面的例子中,我们使用class关键字创建了一个名为Dog的类。
2. 对象
对象是具有与之相关联的状态和行为的实体。它可以是任何现实世界对象,如鼠标、键盘、椅子、桌子、笔等。整数、字符串、浮点数、偶数数组和字典都是对象。更具体地,任何单个整数或任何单个字符串都是对象。数字12是一个对象,字符串“Hello,world”是一个对象,列表是一个可以容纳其他对象的对象,依此类推。
对象由以下部分组成:
- 状态:由对象的属性表示。它还反映了对象的属性。
- 行为:它由对象的方法表示。它还反映了一个对象对其他对象的响应。
- 身份:它为对象提供唯一的名称,并使一个对象能够与其他对象交互。
为了理解状态、行为和身份,让我们以类dog为例(如上所述)。
- 身份可以被认为是狗的名字。
- 状态或属性可以被认为是狗的品种、年龄或颜色。
- 行为可以被认为是狗在吃东西还是睡觉。
创建对象
这将创建一个名为obj的对象,它属于上面定义的Dog类。在深入研究对象和类之前,让我们了解一些基本的关键字,这些关键字将在处理对象和类时使用。
obj = Dog()
Python 中的self理解
- 类方法在方法定义中必须有一个额外的第一个参数。我们在调用方法时不给予这个参数一个值,Python提供了它
- 如果我们有一个不带参数的方法,那么我们仍然必须有一个参数。
- 这类似于C++中的this指针和Java中的this引用。
当我们调用这个对象的方法myobject.method(arg 1,arg 2)时,Python会自动将其转换为MyClass.method(myobject,arg 1,arg 2)–这就是特殊的self的全部内容。
Python __init__方法
__init__方法类似于C++和Java中的构造函数。一个类的对象被实例化,它就运行。该方法可用于对对象进行任何初始化。现在让我们定义一个类,并使用self和__init__方法创建一些对象。
创建具有类和实例属性的类和对象
class Dog:
# class attribute
attr1 = "mammal"
# Instance attribute
def __init__(self, name):
self.name = name
# Driver code
# Object instantiation
Rodger = Dog("Rodger")
Tommy = Dog("Tommy")
# Accessing class attributes
print("Rodger is a {}".format(Rodger.__class__.attr1))
print("Tommy is also a {}".format(Tommy.__class__.attr1))
# Accessing instance attributes
print("My name is {}".format(Rodger.name))
print("My name is {}".format(Tommy.name))
输出
Rodger is a mammal
Tommy is also a mammal
My name is Rodger
My name is Tommy
使用方法创建类和对象
这里,Dog类定义了两个属性:
- attr1是设置为值“mammal”的类属性。类属性由类的所有实例共享。
- __init__是一个特殊的方法(构造函数),用于初始化Dog类的实例。它需要两个参数:self(引用正在创建的实例)和name(表示狗的名字)。name参数用于为Dog的每个实例分配一个name属性。
class Dog:
# class attribute
attr1 = "mammal"
# Instance attribute
def __init__(self, name):
self.name = name
def speak(self):
print("My name is {}".format(self.name))
# Driver code
# Object instantiation
Rodger = Dog("Rodger")
Tommy = Dog("Tommy")
# Accessing class methods
Rodger.speak()
Tommy.speak()
My name is Rodger
My name is Tommy
3. 继承
继承是一个类从另一个类派生或继承属性的能力。派生属性的类称为派生类或子类,从中派生属性的类称为基类或父类。继承的好处是:
- 它很好地代表了现实世界的关系。
- 它提供了代码的可重用性。我们不必一遍又一遍地写同样的代码。此外,它允许我们在不修改类的情况下向类添加更多功能。
- 它本质上是可传递的,这意味着如果类B从另一个类A继承,那么B的所有子类都将自动从类A继承。
继承的类型
- 单一继承:单级继承使派生类能够从单亲类继承特性。
- 多级继承:多级继承使派生类能够从直接父类继承属性,而直接父类又从父类继承属性。
- 分层继承:分层继承使多个派生类能够从父类继承属性。
- 多重继承:多级继承使一个派生类能够从多个基类继承属性。
# parent class
class Person(object):
# __init__ is known as the constructor
def __init__(self, name, idnumber):
self.name = name
self.idnumber = idnumber
def display(self):
print(self.name)
print(self.idnumber)
def details(self):
print("My name is {}".format(self.name))
print("IdNumber: {}".format(self.idnumber))
# child class
class Employee(Person):
def __init__(self, name, idnumber, salary, post):
self.salary = salary
self.post = post
# invoking the __init__ of the parent class
Person.__init__(self, name, idnumber)
def details(self):
print("My name is {}".format(self.name))
print("IdNumber: {}".format(self.idnumber))
print("Post: {}".format(self.post))
# creation of an object variable or an instance
a = Employee('Rahul', 886012, 200000, "Intern")
# calling a function of the class Person using
# its instance
a.display()
a.details()
输出:
Rahul
886012
My name is Rahul
IdNumber: 886012
Post: Intern
在上面,我们创建了两个类,即Person(父类)和Employee(子类)。Employee类继承自Person类。我们可以通过employee类使用person类的方法,如上面代码中的display函数所示。子类也可以修改父类的行为,如通过details()方法所看到的。
4. 多态
多态仅仅意味着具有多种形式。例如,我们需要确定给定种类的鸟是否会飞,使用多态性,我们可以使用单个函数来完成这一点。
class Bird:
def intro(self):
print("There are many types of birds.")
def flight(self):
print("Most of the birds can fly but some cannot.")
class sparrow(Bird):
def flight(self):
print("Sparrows can fly.")
class ostrich(Bird):
def flight(self):
print("Ostriches cannot fly.")
obj_bird = Bird()
obj_spr = sparrow()
obj_ost = ostrich()
obj_bird.intro()
obj_bird.flight()
obj_spr.intro()
obj_spr.flight()
obj_ost.intro()
obj_ost.flight()
输出
There are many types of birds.
Most of the birds can fly but some cannot.
There are many types of birds.
Sparrows can fly.
There are many types of birds.
Ostriches cannot fly.
这段代码演示了Python类中继承和方法重写的概念。它展示了子类如何重写父类中定义的方法以提供特定的行为,同时仍然从父类继承其他方法。
5. 封装
封装是面向对象编程(OOP)中的基本概念之一。它描述了包装数据的思想以及在一个单元内处理数据的方法。这就限制了直接访问变量和方法,并可以防止意外修改数据。为了防止意外更改,对象的变量只能由对象的方法更改。这些类型的变量被称为私有变量。
类是封装的一个例子,因为它封装了所有的数据,如成员函数,变量等。
# Creating a Base class
class Base:
def __init__(self):
self.a = "GeeksforGeeks"
self.__c = "GeeksforGeeks"
# Creating a derived class
class Derived(Base):
def __init__(self):
# Calling constructor of
# Base class
Base.__init__(self)
print("Calling private member of base class: ")
print(self.__c)
# Driver code
obj1 = Base()
print(obj1.a)
# Uncommenting print(obj1.c) will
# raise an AttributeError
# Uncommenting obj2 = Derived() will
# also raise an AtrributeError as
# private member of base class
# is called inside derived class
输出
GeeksforGeeks
在上面的例子中,我们创建了c变量作为私有属性。我们甚至不能直接访问这个属性,甚至不能改变它的值。
6. 数据抽象
它向用户隐藏了不必要的代码细节。此外,当我们不想给予代码实现的敏感部分时,这就是数据抽象的由来。
Python中的数据抽象可以通过创建抽象类来实现。