Python基础篇【第十三篇】:面向对象

面向对象编程简称OOP(OOP,object-oriented programming)是一种程序设计思想,OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

面向对象设计简称OOD(OOD,object-oriented design)OOD仅意味着来创建你采用面向对象方式架构来创建系统.

面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。


面向对象常用的术语:
1.类(class):
用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

2.类变量:
类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

3.数据成员:
类变量或者实例变量用于处理类及其实例对象的相关的数据。

4.方法重写:
如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。

5.实例变量:
定义在方法中的变量,只作用于当前实例的类。

6.继承:
即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。

7.实例化:
创建一个类的实例,类的具体对象。

8.方法:
类中定义的函数。

9.对象:
通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。


和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。
Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。
对象可以包含任意数量和类型的数据。


类的综合表现形式:

class ClassName_1:                    #定义类
    def __init__(self, nm, ph):         #定义构造器
        self.nm = nm                    #设置名字
        self.ph = ph
        print('类self指向的内存地址:', self)
        print(self.nm)
        print(self.ph)

    def def_name_1(self, newph):                 #定义方法
        self.nm = self.nm
        self.ph = newph                   #重新命名
        print('方法self指向的内存地址:', self)
        print(self.nm)
        print('新的电话号码:',self.ph)

class ClassName_2(ClassName_1):             #创建子类
    def __init__(self, nm, ph, id, em):
        super(ClassName_2, self).__init__(nm, ph)
        self.id = id
        self.em = em
        print('类self指向的内存地址:', self)
        # print(self.nm)
        # print(self.ph)
        print(self.id)
        print(self.em)

    def def_name_2(self, newemail):
        self.id = self.id
        self.em = newemail
        print('类self指向的内存地址:', self)
        # print(self.nm)
        # print(self.ph)
        print(self.id)
        print(self.em)
运算结果:
/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/zk/PycharmProjects/old_boy/week06/class_面向对象.py
类self指向的内存地址: <__main__.ClassName_1 object at 0x101b84208>
小明
110
实例化ret_2指向的内存地址: <__main__.ClassName_1 object at 0x101b84208>
方法self指向的内存地址: <__main__.ClassName_1 object at 0x101b84208>
小明
新的电话号码: 110
类self指向的内存地址: <__main__.ClassName_2 object at 0x101b842e8>
小红
119
类self指向的内存地址: <__main__.ClassName_2 object at 0x101b842e8>
66
123@qq.com
实例化ret_2指向的内存地址: <__main__.ClassName_2 object at 0x101b842e8>
类self指向的内存地址: <__main__.ClassName_2 object at 0x101b842e8>
66
qwe@163.com
方法self指向的内存地址: <__main__.ClassName_2 object at 0x101b842e8>
小红
新的电话号码: 1233333333333333333

Process finished with exit code 0

类的专有方法:

__init__ : 构造函数,在生成对象时调用
__del__ : 析构函数,释放对象时使用
__repr__ : 打印,转换
__setitem__ : 按照索引赋值
__getitem__: 按照索引获取值
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__div__: 除运算
__mod__: 求余运算
__pow__:乘方

运算符重载:

class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b


    def __str__(self):
        print(self.a,type(self.a))
        print(self.b,type(self.b))
        return 'Vector (%d, %d)' %(self.a, self.b)


    def __add__(self, other):
        print(self.a,type(self.a))
        print(self.b,type(self.b))
        return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2)

 运算结果:

Vector (7, 8)

 

面向对象的特性:封装.继承.多态

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

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

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

#----------------封装----------------
class Person:
    def __init__(self,name,age,weight):         #构造方法,创建对象时自动执行
        self.Name = name
        self.Age = age
        self.Weight = weight

    def chi(self):
        self.Weight = self.Weight + 2
        print(self.Weight)

    def jianshen(self):
        self.Weight = self.Weight - 1
        print(self.Weight)

# 根据Person创建对象
# 自动执行Personl类的__init__方法
o1 = Person('小明',22,120)                     #将小明和22,120分别封装到name,age,weight属性中

# 实例化
o1.jianshen()

o1.chi()

 运行结果:

119
121

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

# ---------------继承-----------------
class Animals:

    def chi(self):
        print(self.name + "\t吃")

    def he(self):
        print(self.name + "\t喝")

    def piao(self):
        print("嫖娼-1")

class Uncle:
    def du(self):
        print("赌博")

    def piao(self):
        print("嫖娼-2")

class Dog(Animals,Uncle):
    def __init__(self,name):
        self.name = name

    def jiao(self):
        print(self.name + "\t汪汪汪~")

alex = Dog("李杰")
alex.piao()
运行结果:
嫖娼-1

 

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

注:除了子类和父类的称谓,你可能看到过 派生类 和 基类 ,他们与子类和父类只是叫法不同而已。

多继承:
Python的类可以继承多个类,Java和C#中则只能继承一个类
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()

 

多态:

    python不支持多态


类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的方法
在类地内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 slef.__private_methods。
 

posted @ 2016-06-01 19:08  汪汪小喵咪  阅读(221)  评论(0编辑  收藏  举报