python--面对对象编程

面对对象基础

使用面向对象编程能够大幅度提高程序的复用率,降低后期的维护成本,提高软件的可靠性和可伸缩性。

面向过程与面向对象

面向过程:首先分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候依次调用这些函数即可。以“五子棋”程序为例,面向过程的设计思路就是首先分析问题的步骤:①开始游戏;②黑子先走;③绘制画面;④判断输赢;⑤轮到白子;⑥绘制画面;⑦判断输赢;⑧返回步骤②;⑨输出最后结果。

面向对象:编程思想把构成问题的事务分解成各个对象,这些对象没有先后的顺序,它们共同作用构成了整个系统。以“五子棋”程序为例,整个系统可以划分为 3 类对象:①玩家对象,即黑白双方;②棋盘对象,负责绘制画面;③规则系统,负责判定诸如犯规、输赢等。第一类对象负责接受用户输入,并告知第二类对象棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象来对棋局进行判定。

面向对象基础概念

  1. 基本概念
    (1)对象:一切事务皆对象。
    (2)类:类是对象的模板。一个类所包含的方法和数据描述一组对象的共同属性和行为。
  2. 主要特征
    (1) 封装性:将数据和方法封装在类中,用户只能看到公有方法,并不知道实现方法的细节。类相当于一个黑箱。
    (2) 继承性:一个类可以定义另一个类。继承分为单继承(一个子类只有一父类)和多重继承(一个类有多个父类)。
    (3) 多态性:同一消息为不同的对象接受时可产生完全不同的行为。

类的定义与使用

类的定义

class Animal:
    count=0
    legs=[]
    #类的初始化函数
    def __init__(self,name):
        self.name=name
        
    #创建类中的函数
    def eat(self):
        print("I can eat")
  • __init__是该类的初始化函数,当创建一个对象后,会自动调用__init__,用于初始化一个对象的数据;
  • 任何python类方法的第一个参数都是self,这个参数类似于java中的this。

类的使用

类是抽象的模板,对象是类的实例。python创建一个对象不需要使用new操作符,直接调用类函数。

dog1=Animal('dog')
dog1.eat()  
# I can eat

类的属性和方法

类的属性

class Animal:
    count=0
    legs=[]
    #类的初始化函数
    def __init__(self,name):
        self.name=name

    #创建类中的函数
    def eat(self):
        print("I can eat")
dog1=Animal('dog')
print(Animal.count) #0
print(Animal.legs) #[]
print(dog1.name) #dog

count、legs、name为该类的数据属性,这些数据属性分为类数据属性(count、legs)和实例数据属性(name)。

类的特殊属性:

类属性含义
__name__类的名字
__doc__类的文档字符串
__bases__类的所有父类组成的元素
__dict__类的属性组成的字典
__module__类所属的模块
__class__类对象的类型

类的方法

在一个类中,可能出现三种方法:实例方法、类方法和静态方法。
(1) 实例方法
实例方法的第一个参数必须是"self"。

class Animal:
    count=0
    legs=[]
    #类的初始化函数
    def __init__(self,name):
        self.name=name

    #创建类中的函数
    def eat(self):
        print("I can eat")
dog1=Animal('dog')
dog1.eat()  #I can eat

(2) 类方法
类方法以cls作为第一个参数,cls表示类本身,定义时使用@classmethod装饰器。通过cls可以访问类的相关属性。

class Animal:
    count=0
    legs=[]
    #类的初始化函数
    def __init__(self,name):
        self.name=name

    @classmethod
    def printClassInfo():
        print(cls.__name__)
        
Animal.printClassInfo() #Animal
cat=Animal('cat')
cat.printClassInfo() #Animal

(3) 静态方法
静态方法没有参数限制,既不需要实例参数,也不需要类参数,定义的时候使用@staticmethod装饰器。

class Animal:
    count=5
    legs=[]
    #类的初始化函数
    def __init__(self,name):
        self.name=name

    @staticmethod
    def printClassAttr():
        print(Animal.count)

Animal.printClassAttr() # 5
cat=Animal('cat')
cat.printClassAttr() # 5

实例方法只能通过实例进行调用;静态方法和类方法,可以通过类名和实例两种方式进行调用。

特殊的类方法:

类属性含义
__del__析构函数
__len__获得长度
__call__函数调用
__dict__类的属性组成的字典
__add__加运算
__sub__减运算

访问控制

Python中没有像Java中private、protected等访问控制的关键字,但在Python编码中,使用一些约定来进行访问控制。
(1) 名称前的双下划线
如果一个函数、类方法或属性的名字以两个下划线开始(但不是结束),它是私有的。
(2) 名称前的单下划线
在Python中,一般约定以单下划线“_”开头的变量、函数为模块私有的。也就是说“from 模块名 import *”将不会引入以单下划线“_”开头的变量、函数。
(3) 名称前后的双下划线
这种用法表示Python中特殊的方法名。例如,当定义一个类时,经常会重写“__init__”方法。

构造函数和析构函数

(1) __init__ ()构造方法
构造函数是一种特殊的方法,主要用来在创建对象时初始化对象。若实现了__init__()方法,就调用这个方法。

class test():
    def __init__(self):
        print("__init__")
    def __del__(self):
        print("__del__")
    def common(self):
        print("common")
t1=test()

调用结果:

__init__
__del__

说明在创建t1时,__init__()方法被执行了。

(2) __del__()析构方法
当使用del删除对象时,会调用它本身的析构函数,另外当对象在某个作用域中调用完毕,也会调用析构函数,用来释放内存空间

类的继承

当一个类被其他的类继承时,被继承的类称为基类,又称为父类。继承其他类属性的类称为派生类,又称为子类。

类的简单继承

class Animal:
    def eat(self):
        print(self.name+' eat')
    def drink(self):
        print(self.name+' drink')
class Cat(Animal):
    def __init__(self,name):
        self.name=name
    def miaomiao(self):
        print('miaomiao')
class Dog(Animal):
    def __init__(self,name):
        self.name=name
    def wangwang(self):
        print('wangwang')
c1=Cat('jerry')
c1.eat()
d1=Dog('mike')
d1.drink()

运行结果:

jerry eat
mike drink

当在Python中出现继承的情况时,一定要注意初始化函数__init__的行为。
(1) 如果子类没有定义自己的初始化函数,父类的初始化函数会被默认调用;如果要实例化子类的对象,则只能传入父类的初始化函数对应的参数,否则会出错。
(2) 如果子类定义了自己的初始化函数,而没有显式调用父类的初始化函数,则父类的属性不会被初始化。
(3) 如果子类定义了自己的初始化函数,显式调用父类,则子类和父类的属性都会被初始化。

类的多重继承

使用多重继承需要注意圆括号中父类名字的顺序。如果父类中有相同的方法名,而在类中使用时未指定父类名,则Python解释器将从左至右搜索。

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):
    pass
a=A()
a.bar() #B.bar
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(C,B):
    pass
a=A()
a.bar()  # C.bar

类的重载

当继承某一个或几个类时,当前定义的类也继承父类的方法。重载,是指重新定义父类中的方法。

方法重载

方法重载指的是重载父类的方法。

#重载了构造函数和show父类的方法
class People:
    def __init__(self,name):
        self.name=name
    def show(self):
        print('father')
    def setName(self,name):
        print(name)


class P1(People):
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def show(self):
        print('son')
p1=P1('mike',23)
p1.show()
p1.setName('marry')

运算符重载

在类中,运算符对应类中的一些专有方法。因此运算符的重载实际上是对运算符对应的专有方法的重载。
例如+操作符对应__add__方法:

class List:
    __mylist=[]
    def __init__(self,*args):
        self.__mylist=[]
        for arg in args:
            self.__mylist.append(arg)
    def __add__(self, n):
        for i in range(0,len(self.__mylist)):
            self.__mylist[i]=self.__mylist[i]+n
        return self.__mylist
    def show(self):
        print(self.__mylist)
list=List(1,2,3,4,5)
list.show()  # [1, 2, 3, 4, 5]
list1=list + 5
print(list1)  #[6, 7, 8, 9, 10]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值