Python面向对象编程

Python面向对象编程

面向对象程序设计

所谓编程范式,就是程序员使⽤特定的语法+数据结构和算法编写代码,最终的⽬的是告诉计算机来解析并且来执⾏这些代码。

在编程范式的领域,主要分为⾯向过程的编程⽅式和⾯向对象的编程⽅式,具体如下:

⾯向过程,也就是说流程化的⼲⼀件事,严格的按照顺序来进⾏,很明显,这与⽬前的敏捷模式格格不⼊的。 但是它也是具备优点的,它的优点是把复杂的问题流程化,进⼀步达到简单化的过程。所谓优点也是缺点,在这里体现的⾮常明显,正因为对进⾏了流程化,也就导致了⼀套流程只能解决⼀个问题,⽐如⽣产汽⻋的流⽔线等,它的可扩展性存在很⼤的缺陷,因此也级有了⾯向对象的编程⽅式。

⾯向对象的编程,在上帝的视⻆下,来审视万事万物,⼀切皆是对象。与⾯向过程的机械式的编程⽅式而言, ⾯向对象的编程⽅式更加看重的是对象,而非过程,它的优点具体为:

  1. 解决了面向过程可扩展性的问题,在软件的⻆度而言,⾯向对象的程序设计只是来解决程序扩展性的问题

面向对象的三大特性: 1、封装 2、继承 3、多态

类与对象n

所谓类就是类别,类简单的理解就是⼀系列对象相似的特征与技能的结合体。⽐如我们定义⼀个⼈的类,那么里面 的方法就是⼈的特征。在程序⾥⾯,需要特别强调的是先定义类,再使⽤类(对类进⾏实例化)。在Python中,定 义类的关键字是class,所有类的基类是object。如下定义⼀个人的类,

备注:在定义类的时候,类的⾸字⺟⼀定要⼤写。

'''
面向对象:
站在上帝的视角,世界万物一切皆是对象,我们把拥有共同的属性分为一类,这就是class的由来

python2:经典类
python3:新式类
'''

#类的首字母必须大写
#类里面编写的方法,基本本质上等价于函数式编程里面编写的函数
def show():
    print('this is a function')

class Person(object):

    def show(self):
        print('this is a class')

show()
'''
类里面的方法怎么调用?
1、首先对类进行实例化的处理
2、使用实例后的对象来调用类里面的方法
'''

#对类进行实例化的过程,obj是类实例化后的对象(这个名称只要符合变量的名称就可以了)
obj=Person()
obj.show()

class Person(object):
    #初始化(针对类的初始化)
    #初始化方法
    def __init__(self,name,age):#属性(name,age)
        #实例化属性的过程
        self.name=name
        self.age=age
    
  
    def show(self):
        print('my name is {name},and my age is {age}'.format(name=self.name,age=self.age))
        
    #析构方法
    #清理
    def __del__(self):
        print('执行结束')    
        
#类实例化的过程也是针对类里面的__init__方法初始化的过程
'''
方法执行的顺序:
1、先执行__init__方法
2、执行具体调用的方法
3、最后执行__del__方法
'''
obj=Person(name='ghj',age='22')
obj.show()

属性查找

数据属性

类的数据属性是针对所有对象共享的,也就是说针对⼀个类进⾏实例化后的对象,调用数据属性,它的内存地址都是⼀样的

class Person(object):
    #数据变量
    #全局变量
    city='xian'
    def __init__(self,name,age):
        #实例化属性的过程
        self.name=name
        self.age=age

    def show(self):
        print('my name is {name},and my age is {age},live in {city}'.format(name=self.name,age=self.age,city=self.city))

'''
数据属性属于类
实例属性属于对象
'''
obj=Person(name='ghj',age='22')
obj.show()

实例属性

里面的sex

class Person(object):
    #数据变量
    #全局变量
    city='xian'
    def __init__(self,name,age):
        #实例化属性的过程
        self.name=name
        self.age=age

    def show(self,sex='boy'):
        print('my name is {name},and my age is {age},live in {city},sex is {sex}'.
              format(name=self.name,age=self.age,city=self.city,sex=sex))

    def info(self,**kwargs):
        return  kwargs

'''
数据属性属于类
实例属性属于对象
'''
obj=Person(name='ghj',age='22')
obj.show()
print(obj.info(name='ghj',age=18,address='xian',work='testDev'))

类的方法

在Python的类⾥⾯,在类里面编写的特性函数称为⽅法,这些⽅法主要分为普通⽅法,特性⽅法,静态⽅法,类⽅法

'''
普通方法
特性方法
'''

class Person(object):
    def show(self):
        print('这是一个普通方法')

    @property
    def info(self):
        print('特性方法是只读属性')

    def login(self,username,password):
        if username=='ghj' and password=='admin':
            return  True
        else:
            return  False

    def profile(self,username,password):
        if self.login(username=username,password=password):
            print('访问个人主页成功')
    
obj=Person()
obj.show()
obj.info
obj.profile(username='ghj',password='admin')

'''
封装;是通过数据属性以及实例属性来体现的
'''
class Person(object):
    def __init__(self,name):
        self.name=name

    def getName(self):
        return self.name

    def setName(self,name):
        self.name=name

    def show(self):
        print(self.name)

obj=Person(name='ghj')
print(obj.getName())
obj.setName(name='admin')
print(obj.getName())

class Person(object):
    def __init__(self,name):
        self.name=name

    def getName(self):
        return self.name

    def setName(self,name):
        if len(name)>2 and len(name)<6:    ///更名格式,如果超限则还是原名
                self.name=name
        else:
            print('名字超过设置长度')

    def show(self):
        print(self.name)

obj=Person(name='ghj')
print(obj.getName())
obj.setName(name='adminff')
print(obj.getName())

下⾯⼀⼀的来解释每个⽅法,具体如下:

普通⽅法:属于对象也属于类

特性⽅法:属于对象,编写特性⽅法的使⽤需要特别注意,该⽅法不能有形式参数,具备只读属性

静态⽅法:属于类,使⽤类名直接调⽤

类⽅法 :属于类,使⽤类名直接可以调⽤

类的继承

在Python⾥⾯,⼀个类是可以继承多个类的。我们可以把类的继承理解为类与类之间的关系,在Python3⾥⾯,类的继承使⽤的算法是MRO的算法。在继承中,继承的类叫⼦类或者派生类,被继承的类称为基类或者是⽗类。

单继承

'''
基类(父类):被继承的类,子类继承父类后,会继承父类里面所有的属性(数据属性&实例属性)以及方法
派生类(子类):继承其他的类,子类继承父类后,能够继承父类里面所有的方法以及属性,当然也可以调用

继承的N个原则:
1、子类可以继承N个父类,但是建议不要超过2个,最多2个
2、上下原则---》如果子类没有重写父类的方法,那么使用的是上下原则
    A、如果子类没重写父类的方法,调用父类的方法,输出的结果是父类里面方法的输出结果
    B、如果子类重写了父类里面的方法,那么调用该重写的方法,输出的结果是子类里面方法的输出结果

方法重写:子类重写了父类里面的方法,重写的目的是父类的方法没有办法满足子类的需求,那么就会重写
'''

class Person(object):
    city='xian'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def show(self):
        print('my name is {name},and age is {age}'.format(name=self.name,age=self.age))

class Student(Person):
    def __init__(self,name,age,score):
        #子类继承父类的实例属性
        # Person.__init__(self,name,age) ///两种方法都可
        super().__init__(name,age)
        self.score=score


    def info(self):
        print('my name is {name},and my age is {age},and score is {score},and city is {city}'.format(
            name=self.name,age=self.age,score=self.score,city=self.city))
    
    def show(self):
        print('我是子类的show method') ///另一个子类

stu=Student('ghj',18,95)
stu.info()
stu.show()    ///子类输出
print(stu.city)

 

 

多继承

从左到右的顺序

'''
3、从左到右原则:一个子类继承多个父类,那么调用方法后,从左到右按线性的方式来寻找

'''

class A(object):
    def show(self):
        print('this is a A')

class B(object):
    def show(self):
        print('this is a B')

class C(A,B):
    pass

c=C()
c.show()   ///找到一个后就不再查找,线性查找,如果都查找不到则会报错

从下到上的顺序

class Person(object):
    def show(self):
        print('我是⼈类')
class Father(Person):
    def show(self):
         print('我是爸爸')
class Son(Father):
 pass

son=Son()
son.show()

其实从下到上的原则思想,主要是应⽤于单继承,但是是多个类之间的继承嵌套。

方法重写

class A(object):
    def show(self):
        print('this is a A')

class B(A):
    def show(self):
        print('this is a B')


c=B()
c.show()

继承原理

在Python的类继承中,其实存在⼀个⽅法解析MRO的列表,它其实就是所有基类的线性顺序列表,

class A(object):
    def show(self):
        print('this is a A')

class B(A):
    def show(self):
        print('this is a B')

class C(B):
    pass

c=C()
print(C.mro())

所以在Python中,基于MRO的解析顺序规则,就会从左到右开始查找基类,如果找到第⼀个匹配的属性类,就会停⽌查找,如果没有,那就继续查找,直到查找到符合要求的为止。MRO其实就是通过⼀个C3线性化算法来实现的,它的核⼼思想为:

⼦类会优先于⽗类检查

多个⽗类会根据它们在列表中的顺序被依次检查

如果对下⼀个类存在两个合法的选择,只能选择第⼀个

深度优先&⼴度优先

Python由于历史的原因,把Python2的类叫经典类,Python3的类叫新式类,其实在Python2中,多个类的继承算法叫深度优先,⽽Python3叫广度优先。

class A(object):
    def show(self):
        print('this is a A')

class B(A):
    pass

class C(A):
    def show(self):
        print('C')

class D(B,C):
    pass

obj=D()
obj.show()
print(D.mro())

Python3顺序:D->B->C->A

Python2顺序:D->B->A

类的多态

多态性

多态的优势具体可以总结为如下⼏点,具体为:

增加了持续的灵活性

增加了持续的额外扩展的功能

先得理解什么是一切皆对象

'''
一切皆对象(变量,函数,类)
'''
name='ghj'
def func():
    print('hello world')

class Person(object):
    def show(self):
        print('This is a Class')

obj1=name
print(obj1)
obj2=func
obj2()
obj3=Person
obj3().show()

以具体的案例来演示这部分

class Animal(object):
    def talk(self):
        print('动物会叫')

class Cat(Animal):
    def talk(self):
        print('猫也是会叫的')

class Dog(Animal):
    def talk(self):
        print('狗也是会叫的')

def func(animal):
    animal.talk()

dog=Dog()
func(animal=dog)
cat=Cat()
func(animal=cat)

所以多态性我们也是可以理解为对Dog而言只是产⽣了⼀个对象,使⽤者完全可以在不需要修改自己的情况下,就能够调⽤Dog对象的talk的⽅法。

鸭⼦类型

在Python里面,所谓鸭⼦类型就是指“如果看起来像,叫声像而且走路起来像鸭⼦,那么它就是鸭⼦”。

类案例实战

针对前面的登录案例,用类的方式来进行编写

import json

class Main(object):
    def out(self):
        username=input('请输入账户:\n')
        password=input('请输入密码:\n')
        return username,password
    def register(self):
        username,password=self.out()
        temp=username+'|'+password
        json.dump(temp,open('user.md','w'))

    def login(self):
        username,password=self.out()
        lists=str(json.load(open('user.md','r'))).split('|')
        if username==lists[0] and password==lists[1]:
            return True
        else:
            return False

    def profile(self):
        lists=str(json.load(open('user.md','r'))).split('|')
        if self.login():
            print('{nick}登陆成功'.format(nick=lists[0]))
        else:
            print('账户或者密码错误')

    def main(self):
        while True:
            try:
                f=int(input('1、注册 2、个人主页 3、退出\n'))
                if f==1:
                    self.register()
                elif f==2:
                    self.profile()
                elif f==3:
                    break
            except:
                continue

if __name__ == '__main__':
    obj=Main()
    obj.main()

 

 

posted on 2022-09-09 16:56  xiaobia1  阅读(136)  评论(0)    收藏  举报