zoukankan      html  css  js  c++  java
  • python学习笔记之---面向对象的三大特性

    面向对象的三个特征:封装,继承,多态
    封装:把数据和操作数据的方法,用类来实现。保证数据的安全性
    继承:子类可以使用父类的共有属性和共有方法。
    多态:参数类型用基类声明,执行的时候会根据传入的对象
          去执行相应的方法,具有不同的效果。
     

    封装
    将对象的数据与操作数据的方法相结合,通过方法将对象的数据与实现细节保护起来,就称为封装。
    封装可以让调用者不用关心对象是如何构建的而直接进行使用。
    #coding=utf-8
    class Animal(object):
        def __init__(self, name):
        #构造方法一个对象创建后会立即调用此方法
            self.Name = name
            print (self.Name)
    
        def accessibleMethod(self):
        #绑定方法对外公开
            print ("I have a self! current name is:")
            print (self.Name)
            print ("the secret message is:")
            self.__inaccessible()
    
        def __inaccessible(self):
        #私有方法对外不公开以双下划线开头
            print ("U cannot see me...")
    
        @staticmethod
        def staticMethod():
        # self.accessibleMethod() #在静态方法中无法
        #直接调用实例方法直接抛出NameError异常
            print("this is a static method")
    
        def setName(self,name): #访问器函数
            print ("setName:")
            self.Name=name
    
        def getName(self): #访问器函数
            print ("getName:")
            return self.Name
    
    a = Animal("learns")
    print (a.getName)
    a.setName("sr")
    print ("new name:",a.getName())
    a.staticMethod()
    a.accessibleMethod()

    E:>py -3 a.py
    learns
    <bound method Animal.getName of <__main__.Animal object at 0x0000000003ED6160>>
    setName:
    getName:
    new name: sr
    this is a static method
    I have a self! current name is:
    sr
    the secret message is:
    U cannot see me...

     
     
     

    继承
    #单继承:子类具备所有父类的共有变量和共有方法(除私有的)
    如果子类没有定义__init__构造方法,会自动调用父类的。
    好处:站在老爸的肩膀上,增加属性,增加方法
          在原有的基础上进行扩展。
    class Person:
        count = 0 #类变量
        nation = "中国"
     
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1
            print("创建了一个新的人")
     
        def get_name(self):#实例方法,必须要实例化
            return self.name
     
    class ChinaPerson(Person):
          #如果子类没有定义__init__构造方法
          #会自动调用父类的。
        def __init__(self,name,gender):
            Person.__init__(self,name,gender)  #调用父类的构造函数:类名+构造函数
     
        def get_gender(self):
            return self.gender
     
    cp = ChinaPerson("吴老师","")
    print(cp.count)
    print(cp.name)
    print(cp.gender)
    print(cp.get_name())
    C:UsersdellDesktop练习6>py -3 0616.py
    创建了一个新的人
    1
    吴老师
    吴老师
     
     
     
    #多继承: 在括号里面写上多个基类(父类)
    子类的构造函数,如果没有实现,则调用第一个基类的构造函数。
    class Person:
        count = 0 #类变量
        nation = "中国"
     
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1
            print("创建了一个新的人")
     
        def get_name(self):#实例方法,必须要实例化
            return self.name
     
    class Bird:
     
        def __init__(self,color):
            print("a bird is birthed!")
            self.color = color
     
        def fly(self):
            print("I can fly in the sky!")
     
    class ChinaBirdPerson(Person,Bird):  #括号里写上多个基类
          #如果子类没有定义__init__构造方法
          #会自动调用父类的。
        def __init__(self,name,gender,color):
            Person.__init__(self,name,gender)  #基类的两个构造方法都要调用,才能使用各自类的变量
            Bird.__init__(self,color)
     
        def get_gender(self):
            return self.gender
     
    cp = ChinaBirdPerson("吴老师","","红色")
    print(cp.color)
    print(cp.get_name()) #继承了Person类的方法
    print(cp.fly()) #继承了Bird类的方法
    C:UsersdellDesktop练习6>py -3 0616.py
    创建了一个新的人
    a bird is birthed!
    红色
    吴老师
    I can fly in the sky!
    None
     
     
    #多继承,当继承的类存在同名的方法,调用时先执行左边的类Person,如果左边没有时会找右边类的方法,
    实例1:
    class Person:
        count = 0 #类变量
        nation = "中国"
     
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1def get_name(self):#实例方法,必须要实例化
            return self.name
        
     
    class Bird:
     
        def __init__(self,color):
            self.color = color
     
        def fly(self):
            print("I can fly in the sky!")
     
        def get_name(self):#实例方法,必须要实例化
            return "bird has no name"
     
    class ChinaBirdPerson(Person,Bird):
          #如果子类没有定义__init__构造方法
          #会自动调用父类的。
        def __init__(self,name,gender,color):
            Person.__init__(self,name,gender)
            Bird.__init__(self,color)
     
        def get_gender(self):
            return self.gender
     
    cp = ChinaBirdPerson("吴老师","","红色")
    print(cp.get_name())
    E:>py -3 a.py
    吴老师
     
    实例2:(Person类里没有get_name方法,会调用Bird类的get_name方法)
    class Person:
        count = 0 #类变量
        nation = "中国"
    
    
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1
    
    
    class Bird:
    
    
        def __init__(self,color):
            self.color = color
    
    
        def fly(self):
            print("I can fly in the sky!")
    
    
        def get_name(self):#实例方法,必须要实例化
            return "bird has no name"
    
    
    class ChinaBirdPerson(Person,Bird):
          #如果子类没有定义__init__构造方法
          #会自动调用父类的。
        def __init__(self,name,gender,color):
            Person.__init__(self,name,gender)
            Bird.__init__(self,color)
    
    
        def get_gender(self):
            return self.gender
    
    
    cp = ChinaBirdPerson("吴老师","","红色")
    print(cp.get_name())
    E:>py -3 a.py
    bird has no name
     
     
    #python3多继承情况下找同名方法的时候,按照深度优先原则查找
    从父类、爷爷类去查找方法,叫做深度优先
    从多继承的同级类去查找方法,叫做广度优先
    class P:
        def get_name(self):
            return "P name!"    
        pass
     
    class Person(P):
        count = 0 #类变量
        nation = "中国"
     
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
            Person.count +=1
            print("创建了一个新的人")
     
        
     
    class Bird:
     
        def __init__(self,color):
            print("a bird is birthed!")
            self.color = color
     
        def fly(self):
            print("I can fly in the sky!")
     
        def get_name(self):#实例方法,必须要实例化
            return "bird has no name"
     
    class ChinaBirdPerson(Person,Bird):
          #如果子类没有定义__init__构造方法
          #会自动调用父类的。
        def __init__(self,name,gender):
            Person.__init__(self,name,gender)
            #Bird.__init__(self,color)
     
        def get_gender(self):
            return self.gender
     
    cp = ChinaBirdPerson("吴老师","")
    print(cp.get_name())
    C:UsersdellDesktop练习6>py -3 0616.py
    创建了一个新的人
    P name!
     p  -->get_name(爷爷类)
           Person(父类)                Bird-->get_name(父类)
              ChinaBirdPerson(孙类)
     
    cp.get_name()
     
     
     

    多态
    多态意味着可以对不同的对象使用同样的操作,但它们可能会以多种形态呈现出结果。
    在Python中,任何不知道对象到底是什么类型,但又需要对象做点什么的时候,都会用到多态。

    实例:

    class Mobile():
        def get_country(self):
            pass
    
    class HuaWei(Mobile):
        def get_country(self):
            print('China')
    
    class Iphone(Mobile):
        def talk(self):
            print('America')
    
    class SanXing(Mobile):
        def get_country(self):
            print('Korea')
    
    #Python的多态性是指:在不考虑实例类型的情况下使用实例,也就是说不同类型的实例有相同的调用方法。
    #HuaWei、Iphone、SanXing都有get_country方法,我们可以定义一个统一的接口来实现:
    def func(obj):
        obj.get_country()  #多态一定会调用实例的方法
    
    
    print(func(HuaWei()))  #调用HuaWei的实例方法
    print(func(Iphone()))
    print(func(SanXing()))

    E:>py -3 a.py
    China
    None
    None
    Korea
    None

     
    工厂模式与多态的区别?例子:
    def cook_factory(food):
        return food()  #工厂函数,只返回实例,不做调用
        food().getData()#调用了实例的方法,多态
     #方法多态:
    #coding=utf-8
    class calculator:
        def count(self,args):
            return 1
    calc=calculator()
    #自定义类型
    
    from random import choice
    #obj是随机返回的类型不确定
    obj=choice(['hello,world',[1,2,3],calc])
    print(obj)
    print(type(obj))
    print(obj.count('a')) #方法多态

    第一次执行程序:

    E:>py -3 a.py
    hello,world
    <class 'str'>
    0

    第二次执行程序:

    E:>py -3 a.py
    [1, 2, 3]
    <class 'list'>
    0

    呈现结果:程序不变每次执行结果不同。
     
     
    #多态---“鸭子类型”
    #coding=utf-8
    class Duck(object):
        def quack(self):
            print ("Quaaaaaack!")
        def feathers(self):
            print ("The duck has white and gray feathers.")
    
    class Person(object):
        def quack(self):
            print ("The person imitates a duck.")
        def feathers(self):
            print ("The person takes a feather from the ground and shows it.")
    
    def in_the_forest(duck):
            duck.quack()
            duck.feathers()
    
    def game():
        donald = Duck()
        john = Person()
        in_the_forest(donald)
        in_the_forest(john)
    
    game()

    E:>py -3 a.py
    Quaaaaaack!
    The duck has white and gray feathers.
    The person imitates a duck.
    The person takes a feather from the ground and shows it.

    就in_the_forest函数而言,参数对象是一个鸭子类型,它实现了方法多态。
    但是实际上我们知道,从严格的抽象来讲,Person类型和Duck完全风马牛不相及

     
     #运算符多态
    #coding=utf-8
    def add(x,y):
        return x+y
    
    print (add(1,2)) #输出3)
    print (add("hello,","world") )#输出hello,world
    print (add(1,"abc")) #将抛出异常 TypeError,不同类型不能相加'

    E:>py -3 a.py
    3
    hello,world
    Traceback (most recent call last):
    File "a.py", line 7, in <module>
    print (add(1,"abc")) #将抛出异常 TypeError,不同类型不能相加'
    File "a.py", line 3, in add
    return x+y
    TypeError: unsupported operand type(s) for +: 'int' and 'str'

    Python的加法运算符是”多态“的,理论上,我们实现的add方法支持任意支持加法的对象,
    但是我们不用关心两个参数x和y具体是什么类型。

     
  • 相关阅读:
    Python安装及编辑器UliPad安装
    安装配置Django开发环境(Eclipse + Pydev)
    VsSDK_sfx.exe 安装出错
    [转]代码分析工具FxCop1.36之一:介绍与使用
    [转]IBM Rational系列产品介绍
    [转]C#控件——DataGridView单元格文本自动换行
    [转]FrameWork4.0的兼容问题 .
    【整理】C# ToString格式字符串整理(Format)(数字、日期和枚举的标准格式设置说明符)(SamWang)
    [转]史上最好的20本敏捷开发书籍
    [转]C#数字千分位问题
  • 原文地址:https://www.cnblogs.com/wenm1128/p/11716543.html
Copyright © 2011-2022 走看看