文章目录
1. 什么是面向对象
2. 面向对象术语介绍
3. 类的定义与使用
3.1 类的定义
3.2 self用法解释
3.3 类属性和实例属性
3.3.1 类属性
3.3.2 实例属性
3.4 实例方法、类方法
3.4.1 实例方法
3.4.2 类方法
4.总结
1. 什么是面向对象
面向对象( Object-Oriented Programming)是现代编程语言都存在的一种编程方式,如果你使用过C语言会发现,每当需要实现一个功能时都需要创建一个一个的函数来实现,这是面向过程。如果你使用过C++或者JAVA就会发现,当实现一个功能时,会把这个功能需要的属性和函数抽象出来封装成一个整体,程序员再对这个整体进行操作,这个整体也就叫做类,类实例出的东西叫做对象。
下面贴上维基百科)的解释:
面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的编程典范,同时也是一种程序开发的抽象方针。它可能包含数据、特性、代码与方法。对象则指的是类(class)的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象。
面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反:传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。目前已经被证实的是,面向对象程序设计推广了程序的灵活性和可维护性,并且在大型项目设计中广为应用。此外,支持者声称面向对象程序设计要比以往的做法更加便于学习,因为它能够让人们更简单地设计并维护程序,使得程序更加便于分析、设计、理解。反对者在某些领域对此予以否认。
当我们提到面向对象的时候,它不仅指一种程序设计方法。它更多意义上是一种程序开发方式。在这一方面,我们必须了解更多关于面向对象系统分析和面向对象设计(Object Oriented Design,简称OOD)方面的知识。许多流行的编程语言是面向对象的,它们的风格就是会透由对象来创出实例。
2. 面向对象术语介绍
在正式具体介绍面向对象技术前,我们需要先了解一些面向对象的术语,以便在后续内容中能够明白对应的意思。
类:用于描述具体相同属性和方法的对象的集合。类定义了集合中每个对象共有的属性和方法。对象是类的实例。
#基本语法
class MyClass:
#类的属性
#类的方法
1
2
3
4
类变量(类属性):类变量在整个实例化的对象中是公用的。类变量定义在类中,且在方法之外。类变量通常不能作为实例变量使用。类变量也称为类属性(类似于Java的static的)。
class Person:
species = "Human" #类属性
print(Person.species) #访问类属性
1
2
3
数据成员:实例属性是对象独有的,通过self关键字定义
方法重写:如果从父类继承的方法不能满足子类的需求,就可以对可以对其进行改写,这个过程称为方法的覆盖(Override),也称为方法的重写。
实例变量(实例属性):定义在方法中的变量只作用于当前实例的类。
class Person:
def __init__(self,name,age):
self.name = name #实例属性
self.age = age #实例属性
person1 = Person('Yui',17)
person2 = Person('Yamada',14)
print(person1.name) #输出:Yui
print(person2.name)
1
2
3
4
5
6
7
8
封装(Encapsulation):对外部世界隐藏对象的工作细节。
继承(Inheritance):一个派生类(derived class)继承基类(base class)的字段和方法。继承允许把一个派生类的对象作为一个基类对象对待,以普通类为基础建立专门的类对象。
多态(Polymorphism):对不同类的对象使用相同的操作。
实例化(Instance):创建一个类的实例、类的基础对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类、派生类可以覆盖基类中的任何方法、方法中可以调用基类中的同名方法。
对象可以包含任意数量和类型的数据。
3. 类的定义与使用
3.1 类的定义
定义一个类:
class Person(object):
#属性
species = "Human" #类属性
#初始化方法
def __init__(self,name,age):
self.name = name #实例属性
self.age = age
#方法
def introduce(self):
print(f'My name is {self.name}, and I am {self.age} years old.')
从这段代码可以看出,定义类时需要使用到关键字class,注意在给类取名时应该做到每个单词的首字母大写,其它字母小写。可以看到Person后面紧接着object代表着该类继承于object,我们要知道所有类都继承自object,所以这个object继承是可以省略的。
注意,无论是类属性还是类方法,对应类来说,它们都不是必须的,可以有也可以没有。另外,python类中的属性和方法所在的位置也是任意的,也就是说,它们是没有固定的前后顺序的。
关于__init__、self,如果你又学过C++/java可以把它们分别理解为构造函数和this指针。关于它们的具体介绍会在文章后面介绍。
3.2 self用法解释
了解完类的定义就可以简单地使用类了。
class MyClass:
i = 111
def f(self):
return 'hello wrold'
use_class = MyClass() #类的实例化
print('调用类的属性:',use_class.i)
print('调用类的方法:',use_class.f())
关于self
在上面的示例中,类中定义了应该f()方法中带有了应该self参数,可是我们并没有传入参数,那么它有什么作用呢?
self 是类中的实例方法的第一个参数,用于指代当前对象的引用。通过 self,可以访问当前对象的属性和方法。虽然名字不固定,但通常约定俗成地使用 self。
等价的代码:
MyClass.f()
#等价于:
MyClass.f(MyClass)
那么为什么需要self的存在呢?
它的作用主要就是用来标识特定的对象的,在学习面向对象的时候,许多老师都会把类比作成一张图纸(你可以理解为房屋设计的图纸),利用这个图纸,你可以设计出许多的房屋(也就是类对象),每个房子的长相都是类似的(都有相同的类变量和类方法),但是尽管它们一样,但是它们的主人是不一样的,也就导致了这些房间的门锁不同。
self它就相当于每个房间的门钥匙,可以保证每个房间的主人仅能进入自己的房间(每个类对象只能调用自己的类对象和类方法)。
就像前面的代码:
MyClass.f()
#等价于:
MyClass.f(MyClass)
#保证每个类对象只能调用自己的类对象和类方法
同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法,也就是说,python会自动绑定类方法的第一个参数指向该方法的对象。这样的话,python解释器就知道到底要操作哪个对象的方法了。
因为,self编译器会自动调用,所以在代码书写的过程中,不需要显示写出来。
class MyClass:
def __init__(self):
print('我是构造方法')
def run(self):
print(self,'我是run方法')
test1 = MyClass()
test1.run()
test2 = MyClass()
test2.run()
打印结果:`
我是构造方法
<__main__.MyClass object at 0x000001FF12F37380> 我是run方法
我是构造方法
<__main__.MyClass object at 0x000001FF12F373B0> 我是run方法
1
2
3
4
从打印结果来看,这两个实例出的对象确实是不同的,两个对象打印的self是不同的。
run()中的self代表该方法的调用者,谁调用该方法,那么self就代表谁。
3.3 类属性和实例属性
在前面的内容里。我们简单的了解了下类属性和实例变量。
无论是类属性还是类方法,都是无法像普通变量或者函数那样,在类外直接使用它们。因为类中的方法和属性都被封装起来了。类就是一个独立的空间,类属性就是类中定义的变量,类方法也是累中定义的函数。
通过总结,我们可以吧类属性分为以下3种类型。
类体中、所有函数之外:此范围定义的变量,称为类属性或类变量。
类体中,所有函数内部:以self.变量名的方式定义的变量,称为实例属性或者实例变量。
类体中,所有函数内部:以self=变量名的方式定义的变量,称为局部变量。