博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Python第五篇】Python面向对象(初级篇)
阅读量:5717 次
发布时间:2019-06-18

本文共 6241 字,大约阅读时间需要 20 分钟。

面向对象编程OOP(Object Oriented Programming)

概述

  • 面向过程:根据业务逻辑从上到下写垒代码
  • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

注:Java和C#来说只支持面向对象编程,而python比较灵活即支持面向对象编程也支持函数式编程

创建类和对象

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

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

  • class是关键字,表示类
  • 创建对象,类名称后加括号即可

ps:类中的函数第一个参数必须是self(详细见:类的三大特性之封装)

   类中定义的函数叫做 “方法”

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建类
class 
Foo:
     
    
def 
Bar(
self
):
        
print 
'Bar'
 
    
def 
Hello(
self
, name):
        
print 
'i am %s' 
%
name
 
# 根据类Foo创建对象obj
obj 
= 
Foo()
obj.Bar()            
#执行Bar方法
obj.Hello(
'wupeiqi'
#执行Hello方法 

ps:函数式的应用场景 --> 各个函数之间是独立且无共用的数据

面向对象三大特性

面向对象的三大特性是指:封装、继承和多态。

一、封装

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

所以,在使用面向对象的封装特性时,需要:

  • 将内容封装到某处
  • 从某处调用被封装的内容

第一步:将内容封装到某处

 self 是一个形式参数,当执行 obj1 = Foo('wupeiqi', 18 ) 时,self 等于 obj1

                              当执行 obj2 = Foo('alex', 78 ) 时,self 等于 obj2

所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都有 name 和 age 属性,在内存里类似于下图来保存。

第二步:从某处调用被封装的内容

调用被封装的内容时,有两种情况:

  • 通过对象直接调用
  • 通过self间接调用

1、通过对象直接调用被封装的内容

上图展示了对象 obj1 和 obj2 在内存中保存的方式,根据保存格式可以如此调用被封装的内容:对象.属性名

1
2
3
4
5
6
7
8
9
10
11
12
13
class 
Foo:
 
    
def 
__init__(
self
, name, age):
        
self
.name 
= 
name
        
self
.age 
= 
age
 
obj1 
= 
Foo(
'wupeiqi'
18
)
print 
obj1.name    
# 直接调用obj1对象的name属性
print 
obj1.age     
# 直接调用obj1对象的age属性
 
obj2 
= 
Foo(
'alex'
73
)
print 
obj2.name    
# 直接调用obj2对象的name属性
print 
obj2.age     
# 直接调用obj2对象的age属性

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

执行类中的方法时,需要通过self间接调用被封装的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class 
Foo:
  
    
def 
__init__(
self
, name, age):
        
self
.name 
= 
name
        
self
.age 
= 
age
  
    
def 
detail(
self
):
        
print 
self
.name
        
print 
self
.age
  
obj1 
= 
Foo(
'wupeiqi'
18
)
obj1.detail()  
# Python默认会将obj1传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18
  
obj2 
= 
Foo(
'alex'
73
)
obj2.detail()  
# Python默认会将obj2传给self参数,即:obj1.detail(obj2),所以,此时方法内部的 self = obj2,即:self.name 是 alex ; self.age 是 78

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

二、继承

继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。

面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

通过继承创建的新类称为“子类”或“派生类”。

被继承的类称为“基类”、“父类”或“超类”。

继承的过程,就是从一般到特殊的过程。

要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。

在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

继承概念的实现方式主要有2类:实现继承、接口继承。

Ø         实现继承是指使用基类的属性和方法而无需额外编码的能力;
Ø         接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法);
在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。
 
抽象类仅定义将由子类创建的一般属性和方法。

OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。

继承示例
#!_*_coding:utf-8_*_#__author__:"Alex Li"   class SchoolMember(object):    members = 0 #初始学校人数为0    def __init__(self,name,age):        self.name = name        self.age = age     def  tell(self):        pass     def enroll(self):        '''注册'''        SchoolMember.members +=1        print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " %(self.name,SchoolMember.members))         def __del__(self):        '''析构方法'''        print("\033[31;1mmember [%s] is dead!\033[0m" %self.name)class Teacher(SchoolMember):    def __init__(self,name,age,course,salary):        super(Teacher,self).__init__(name,age)        self.course = course        self.salary = salary        self.enroll()      def teaching(self):        '''讲课方法'''        print("Teacher [%s] is teaching [%s] for class [%s]" %(self.name,self.course,'s12'))     def tell(self):        '''自我介绍方法'''        msg = '''Hi, my name is [%s], works for [%s] as a [%s] teacher !''' %(self.name,'Oldboy', self.course)        print(msg) class Student(SchoolMember):    def __init__(self, name,age,grade,sid):        super(Student,self).__init__(name,age)        self.grade = grade        self.sid = sid        self.enroll()      def tell(self):        '''自我介绍方法'''        msg = '''Hi, my name is [%s], I'm studying [%s] in [%s]!''' %(self.name, self.grade,'Oldboy')        print(msg) if __name__ == '__main__':    t1 = Teacher("Alex",22,'Python',20000)    t2 = Teacher("TengLan",29,'Linux',3000)     s1 = Student("Qinghua", 24,"Python S12",1483)    s2 = Student("SanJiang", 26,"Python S12",1484)     t1.teaching()    t2.teaching()    t1.tell()
继承示例

那么问题又来了,多继承呢?

  • 是否可以继承多个类
  • 如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢?

1、Python的类可以继承多个类,Java和C#中则只能继承一个类

2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先广度优先

  • 当类是经典类时,多继承情况下,会按照深度优先方式查找
  • 当类是新式类时,多继承情况下,会按照广度优先方式查找

经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。

 

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'class A(B, C):    def bar(self):        print 'A.bar'a = A()# 执行bar方法时# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错# 所以,查找顺序:A --> B --> D --> C# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了a.bar()
经典类多继承
class D(object):    def bar(self):        print 'D.bar'class C(D):    def bar(self):        print 'C.bar'class B(D):    def bar(self):        print 'B.bar'class A(B, C):    def bar(self):        print 'A.bar'a = A()# 执行bar方法时# 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错# 所以,查找顺序:A --> B --> C --> D# 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了a.bar()
新式类多继承

经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错

新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错

注意:在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了

三、多态 

多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!
Python多态示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#_*_coding:utf-8_*_
 
 
class 
Animal(
object
):
    
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
):
        
print
(
'%s: 喵喵喵!' 
%
self
.name)
 
 
class 
Dog(Animal):
    
def 
talk(
self
):
        
print
(
'%s: 汪!汪!汪!' 
%
self
.name)
 
 
 
def 
func(obj): 
#一个接口,多种形态
    
obj.talk()
 
c1 
= 
Cat(
'小晴'
)
d1 
= 
Dog(
'李磊'
)
 
func(c1)
func(d1)

 

转载于:https://www.cnblogs.com/fuyefeng/p/7091975.html

你可能感兴趣的文章
centos5.9使用RPM包搭建lamp平台
查看>>
关于C#面向对象2
查看>>
Javascript String类的属性及方法
查看>>
vim编辑器如何添加或删除多行注释
查看>>
[LeetCode] Merge Intervals
查看>>
iOS开发-按钮的基本使用
查看>>
在QT和SDL搭建的框架中使用OPENGL在SDL窗口上进行绘图
查看>>
REST技术第三步 @BeanParam的使用
查看>>
模板 读入挂!
查看>>
SharePoint 读取 Site Columns 的数据并绑定到DropdownList
查看>>
Python中的对象行为与特殊方法(二)类型检查与抽象基类
查看>>
使用 axios 详解
查看>>
通信基站(dfs回溯,思维)
查看>>
nginx web加密访问
查看>>
iOS - Regex 正则表达式
查看>>
SYS_CONTEXT函数返回IP地址的一些误解
查看>>
第 68 章 Logical Volume Manager (LVM)
查看>>
膝盖中了一箭之康复篇-第八个月暨2月份目标总结
查看>>
IPA提交APPStore问题记录(一)
查看>>
有利于seo优化的网站地图不能取巧
查看>>