Python面向对象编程

python

一、什么是面向对象

  面向对象编程(OOP,Object Oriented Programming)
  OOP三个主要的特征:数据封装、继承和多态。
  所有的程序是由一定的属性和行为对象组成的,不同的对象的访问通过函数调用来完成,对象间所有的交流都是通过方法调用,通过对封装对象数据,提高复用率。

二、创建类和对象

  面向对象编程是一种编程方式,此编程方式的落地需要使用 "类" 和 "对象"来实现,所以,面向对象编程其实就是对 "类" 和 "对象" 的使用。

  类就是一个模板,模板里可包含多个函数,函数里实现一些功能。对象则是根据模板创建的实例,通过实例对象可以执行类中的方法。

class Role (object):

def __init__(self,name):

self.name = name

def buy_weapon(self,weapon):

pass

  class是关键字,定义一个类,其名称为Role,这个类继承了Python的父类,名为object。在类的下面可以看到有很多函数的定义,但在 class中,函数被称为方法,所以这里暂时在一个名为Role类的下面有__init__和buy_weapon方法。

三、封装

  封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。

  所以,在使用面向对象的封装特性时,需要:1.将内容封装到某处 2.从某处调用被封装的内容

class Role (object):    #object是父类,继承父类

def __init__(self,name,role,weapon,life_value): #称为构造方法,根据类创建对象时自动执行

self.name = name #成员变量,self 代表传进来的name,在整个类都可以使用这个变量,把一个局部变量变为了全局变量

self.role = role

self.weapon = weapon

self.life_val = life_value

def buy_weapon(self,weapon):

print("[%s] is buying [%s]" % (self.name,weapon))

self.weapon = weapon

# 把一个抽象的类变成一个具体的过程叫实例化

t1 = Role("Stanley",'Terrorist','Glock',100) #等价于Role(t1,"Stanley",'Terrorist','b11',100),同时将'Stanley'、'Terrorist'、'Glock'和100封装到t1和self的name、role、weapon、life_value属性中

p1 = Role("Tom",'Police','Desert Eagle',90) #Role(p1,"Tom",'Police','Desert Eagle',90)

print("t1's weapon was [%s] before" % t1.weapon)

print("=".center(40,'='))

t1.buy_weapon('AK47') #转换为Role.buy_weapon(t1,'AK47')

print("t1's weapon is [%s] now" % t1.weapon)

Result:

t1's weapon was [Glock] before

========================================

[Stanley] is buying [AK47]

t1's weapon is [AK47] now

  第一个方法__init__是初始化构造方法,构造方法的第一个参数永远是self,表示这个类的对象本身,真正构造对象时,self这个参数不用写,python编译器会自己加上去,构造方法的作用就是对self对象进行赋值,如下面传进来的name赋给self.name,这么做的目的是因为在class中,每个方法依旧是要遵循函数规则的,在函数下面每个变量都是局部变量,在其他函数中并不能相互调用,如此做就把一个局部变量变为全局变量。

  通过self间接调用被封装的内容:

  第二个方法除了编译器会自己加上去的self参数外,weapon参数接收传入的变量,打印调用的参数。在print之后self.name含义是将调用者的name赋值给self。

  接下来要对p1和t1进行实例化,这是将一个抽象的类变成一个具体的过程,生成了p1和t1两个角色。t1 = Role("Stanley",'Terrorist','Glock',100),Python解释器会将此转换为 Role(t1,"Stanley",'Terrorist','Glock',100),这里通过解释器转换后的t1其实就是self。

  现在t1角色进行购买行为,t1.buy_weapon('AK47'),Python解释器会将此转换为 Role.buy_weapon(t1,'AK47'),如上所述此时的t1就是self,也可理解为将t1传入__init__初始化构造方法,就可直接self.name(等价于t1.name)获取到name的变量了(Stanley)。

  综上所述,对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。

四、继承

  继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容,也可理解为由一般到特殊。

class SchoolMember(object):

member_nums = 0

def __init__(self,name,age,sex):

self.name = name

self.age = age

self.sex = sex

self.enroll()

def enroll(self):

print("NO.%s SchoolMember [%s] is enrolled!" % (SchoolMember.member_nums,self.name))

SchoolMember.member_nums += 1 #统计人员数量不可写为self.member_nums += 1,因self实例下没有此变量,两者毫无关联。

def tell(self):

print("Hello, My name is [%s]" % self.name)

class Teacher(SchoolMember): #参数为继承对象

def __init__(self,name,age,sex,course,salary): #如果不写__init__默认就继承了父类的所有属性,但子类需要额外扩展,需先重写再继承

super(Teacher,self).__init__(name,age,sex) #上面进行了重写,再继承回来进行覆盖,推荐新式类语法

#SchoolMember.__init__(self,name,age,sex) #此为经典类语法,不推荐

self.course = course

self.salary = salary

def teaching(self):

print("Teacher [%s] is teaching [%s]" % (self.name,self.course))

class Student(SchoolMember):

def __init__(self,name,age,sex,course,tuition,):

super(Student,self).__init__(name,age,sex)

self.course = course

self.tuition = tuition

def pay_tuition(self):

print("Student [%s] pays tuition [%s] again" % (self.name,self.tuition))

#实例化老师

t1 = Teacher('Stanley',24,'M','Python',1000) #实例化,不可实例化SchoolMember,其只可用来继承

t1 = Teacher('Katrina',29,'M','MySQL',1500) #实例化,不可实例化SchoolMember,其只可用来继承

#实例化学生

s1 = Student('Tim',24,'F','MySQL',10000)

s2 = Student('Bella',27,'M','Python',12000)

print("===========子类使用父类方法============")

t1.tell()

s1.tell()

print("===========子类使用私有方法============")

t1.teaching()

s1.pay_tuition()

Result:

NO.0 SchoolMember [Stanley] is enrolled!

NO.1 SchoolMember [Katrina] is enrolled!

NO.2 SchoolMember [Tim] is enrolled!

NO.3 SchoolMember [Bella] is enrolled!

===========子类使用父类方法============

Hello, My name is [Katrina]

Hello, My name is [Tim]

===========子类使用私有方法============

Teacher [Katrina] is teaching [MySQL]

Student [Tim] pays tuition [10000] again

  此为标准继承示例,其中包含三个类,SchoolMember是父类,Teacher和Student是子类,子类中拥有父类的共同属性,除此之外,子类还需要额外进行扩展,所以在子类中要先重写,再从父类继承回来进行覆盖。在继承语法中super为关键字,不可省略,其参数为子类名称,self,__init__参数为需要继承的属性。相关封装特性详见上一段落,不再累述。父类和子类定义好后,实例化Teacher和 Student,在父类中执行注册方法,每个子类都可调用父类的tell方法,并且每个子类都会包含私有方法teaching和pay_tuition,这就利用继承特性实现了简单的权限限制功能。

  综上所述,对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

五、多态

  多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

  Pyhon不支持多态并且也用不到多态,多态的概念是应用于Java和C#这一类强类型语言中的。那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

  通过Python模拟的多态:

class Animal:

def __init__(self, name): # Constructor of the class

self.name = name

def talk(self): # Abstract method, defined by convention only

raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):

def talk(self):

return 'Meow!'

class Dog(Animal):

def talk(self):

return 'Woof! Woof!'

animals = [Cat('Missy'),

Dog('Lassie')]

for animal in animals:

print animal.name + ': ' + animal.talk()

以上是 Python面向对象编程 的全部内容, 来源链接: utcz.com/z/387917.html

回到顶部