美文网首页Python
类面向对象,封装 继承 多态

类面向对象,封装 继承 多态

作者: 叫我老村长 | 来源:发表于2018-06-18 20:41 被阅读2次

    Python——类、面向对象,封装 继承 多态

    https://www.jianshu.com/u/d959ac37cdde

    1-1F605141A3Q0.png

    面向过程:根据业务逻辑从上到下写代码
    面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程

    人以类聚 物以群分。
    具有相似内部状态和运动规律的实体的集合(或统称为抽象)。
    具有相同属性和行为事物的统称
    类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象
    在Python中编写类的方式如下:

    class Dog():
        '''创建小狗的类'''
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        '''动作方法 play'''
        def sit(self):
            print('狗在玩')
    
    

    方法init()

    init()是一个特殊的方法,每当根据类创建类的实例时,Python都会自动运行这个方法。在这个方法中开头和末尾各有两个下划线。
    避免Python默认方法与普通方法发生名称冲突。
    init()定义中我们传递了三个参数:self、name和age。这个初始化方法中self是必须的。而且还必须位于其他的形参前面。每个与类相关联的方法调用都自动传递实参self它是一个指向实例本身的引用。让实例能够访问类中的属性和方法
    init()方法中定义的两个变量都有前缀self。以self为前缀的变量都可供类中的所有方法使用。
    init()没有并没有显式地包含return语句,但Python自动返回类对象的实例。

    • init_()方法,在创建一个对象时默认被调用,不需要手动调用
    • init(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么init(self)中出了self作为第一个形参外还需要2个形参,例
    • init(self,x,y)
      init(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递进去*

    Python3.0创建类的方法

    • 在Python3.0中创建类
    class ClassName(Object):
            pass
    
    

    根据类创建实例

    my_dog = Dog()
    my_dog.play()
    
    

    为属性指定默认值

    类中的每个属性指定默认值。

     3 class CarPro:
       4     def __init__(self):
       5         self.t=0
       6         self.info='铁皮'
       7         self.SideDishes=[]
       8     def __str__(self):
       9         a=''
      10         for i in self.SideDishes:
      11             a+=i+','
      12         a=a.strip(',')
      13         return '现在加工的是%s,加工了%d分钟'%(self.info,self.t)
      14 
      15     def CarProduct(self,t1):
      16         self.t+=t1
      17         if self.t>=10:
      18             self.info='汽车产生了'
      19         elif self.t>=8:
      20             self.info='汽车各个部件喷涂'
      21         elif self.t>=6:
      22             self.info='汽车各个部件涂胶'
      23         elif self.t>=5:
      24             self.info='汽车各个部位点焊,弧焊,铆焊'
      25         else:
      26             self.info='一堆铁皮'
    
    

    类的继承

    在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物;同理,波斯猫和巴厘猫都继承自猫,而沙皮狗和斑点狗都继承足够。

    • 定义子类时,必须在括号内指定父类的名称
    • 在创建子类的实例时,Python首先需要给父类的所有属性赋值。
    • 创建子类时,父类必须包含在当前文件中,且位于子类前面。
    • 子类中可以使用super()代表父类的引用。
    class Cat(object):
        def __init__(self, name, color="白色"):
            self.name = name
            self.color = color
        def run(self):
            print("%s--在跑"%self.name)
    
    # 定义一个子类,继承Cat类如下:
    class Bosi(Cat):
        def setNewName(self, newName):
            self.name = newName
        def eat(self):
            print("%s--在吃"%self.name)
    bs = Bosi("印度猫")
    print('bs的名字为:%s'%bs.name)
    print('bs的颜色为:%s'%bs.color)
    bs.eat()
    bs.setNewName('波斯')
    bs.run()
    
    

    类——object

    每一个python类都隐含了一个超类:object,这个类是一个非常简单的定义,这个类几乎不做任何事情。

    重写、调用父类方法

    • 所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法

    看几个栗子

    class Cat(object):
        def sayHello(self):
            print("halou-----1")
    class Bosi(Cat):
        def sayHello(self):
            print("halou-----2")
    bosi = Bosi()
    bosi.sayHello()
    >>>
    <__main__.son object at 0x101a45908>
    
    
    class Cat(object):
        def __init__(self,name):
            self.name = name
            self.color = 'yellow'
    class Bosi(Cat):
        def __init__(self,name):
            # 调用父类的__init__方法1(python2)
            #Cat.__init__(self,name)
            # 调用父类的__init__方法2
            #super(Bosi,self).__init__(name)
            # 调用父类的__init__方法3
            super().__init__(name)
        def getName(self):
            return self.name
    bosi = Bosi('xiaohua')
    print(bosi.name)
    print(bosi.color)
    

    多继承

    Python支持多继承,我们知道子类会继承父类中的属性和方法。python中需要继承多个类的时候,使用如下的格式

    class 子类(父类1,父类2):
        pass
    
    

    那么当多个父类都含有相同的方法,会如何执行呢?

    class father1:
        def say(self,args):
            print(args+'father1')
    
    class father2:
        def say(self,args):
            print(args+'father2')
    
    class son(father1,father2):
        pass
    s = son()
    s.say('it say something')
    
    >>>
    it say somethingfather1
    
    

    可以看到,python会执行第一个父类中的相关方法
    我们用图解来解释一下执行顺序

    142800ycssa7s7m00aac2t.png
    # 定义一个父类
    class A:
        def printA(self):
            print('----A----')
    # 定义一个父类
    class B:
        def printB(self):
            print('----B----')
    # 定义一个子类,继承自A、B
    class C(A,B):
        def printC(self):
            print('----C----')
    obj_C = C()
    obj_C.printA()
    obj_C.printB()
    python中是可以多继承的
    父类中的方法、属性,子类会继承
    

    我们根据执行结果,可以看到程序会现在子类中查找要执行的方法和函数,然后会在第一个父类中寻找如果没有找到,会在第二个父类中寻找。如果也没有找到会去父类的公共基类找。
    程序的执行顺序是 1 2 3

    私有化

    • 如果有一个对象,当需要对其进行修改属性时,有2种方法
      对象名.属性名 = 数据 ---->直接修改
      对象名.方法名() ---->间接修改
    • 为了更好的保存属性安全,即不能随意修改,一般的处理方式为
      将属性定义为私有属性
      添加一个可以调用的方法,供调用
    私有化.png

    静态方法和类方法

    是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以’cls’作为第一个参数的名字,就最好用’cls’了),能够通过实例对象和类对象去访问。

    • 静态字段的创建
    class People(object):
        country = 'china'
        @staticmethod
        #静态方法
        def getCountry():
            return People.country
    print (People.getCountry())
    

    类方法

    • 调用get方法
    test = duck('test123')
    print(test.get_name)
    
    
    • 调用setter方法
    test = duck('test123')
    test.set_name = '123test'
    print(test.get_name)
    
    

    使用名称重整保护私有特性

    在前面的Duck例子中,如果直接访问hidden_name还是可以看到对应属性的值。Python对那些需要可以隐藏在类内部的特性有自己的命名规范:由连续的两个下划线开头(__)

    class People(object):
        country = 'china'
        #类方法,用classmethod来进行修饰
        @classmethod
        def getCountry(cls):
            return cls.country
    p = People()
    print (p.getCountry())    #可以用过实例对象引用
    print (People.getCountry())    #可以通过类对象引用
    
    

    类方法还有一个用途就是可以对类属性进行修改:

    对于父类的方法,只要它不符合子类的调用行为,都可以对其重写。

    class People(object):
        country = 'china'
        #类方法,用classmethod来进行修饰
        @classmethod
        def getCountry(cls):
            return cls.country
        @classmethod
        def setCountry(cls,country):
            cls.country = country
    p = People()
    print (p.getCountry())    #可以用过实例对象引用
    print (People.getCountry())    #可以通过类对象引用
    p.setCountry('japan')
    print (p.getCountry())
    print (People.getCountry())
    
    结果显示在用类方法对类属性修改之后,通过类对象和实例对象访问都发生了改变
    
    

    模块

    from part2.classdemo.car import Car
    
    

    import会让Python打开模块car并导入其中的Car类

    • 在一个模块中存储多个类
    • 从一个模块导入多个类
      可根据需要在程序文件中导入任意数量的类。从一个模块中导入多个类时,用逗号分隔导入的个各类。导入必要的类后,就可以根据需要创建每个类的任意数量的实例
    from part2.classdemo.car import Car, ElectricCar
    
    

    模块中的all

    • 被导入的模块,最上边 加入 all = ['one' , 'two'] #添加的方法名称对应的方法。
      在from test import * 导入的情况下, all 所指明的方法会被导入可以使用;其他的不会被*号导入;

    • 通过在文件开头
      all 指定可以被 from……import* 导入的方法

    相关文章

      网友评论

        本文标题:类面向对象,封装 继承 多态

        本文链接:https://www.haomeiwen.com/subject/stugeftx.html