• Python初探第三篇-面向对象


    面向对象进阶学习

    https://www.cnblogs.com/ifyoushuai/p/9140265.html

    类和对象

    Pyhon中的类和对象与C++中的类和对象有着很大的差别,但是他们都是为了对一个对象的属性和方法进行封装,下面就具体讨论Pyhon的类和对象的使用方法。

     一,构造函数

    class Foo:
        def __init__(num):
            self.num = num
    f=Foo(1)

      当使用类初始化对象时自动调用__init__()方法。

     二,类属性和实例属性

      类属性可以通过实例对象或者类本身去调用

    class Foo:
        name = "isFoo"
        def __init__(self):
            pass
    f = Foo
    print(f.name) #isFoo
    print(Foo.name)#isFoo

      实例属性可以通过构造函数来绑定,也可以直接绑定

    class Foo:
        def __init__(self,name):
            self.name = name
    
    f = Foo("Jack")
    f.age = 18
    print(f.name) #Jack #实例属性可以通过属性字典来查看 print(f.__dict__) #{'name': 'Jack', 'age': 18}

     注意事项:

      1,类属性只能通过类调用去修改

      2,若用实例区修改类属性,将直接设置一个与类属性同名的实例属性

    三,继承

      Python3全部是新式类,即类无论是否继承object类,都默认继承它。

    class Animal:
        def eat(self):
            print("%s eating sth" % self.name)
    
    
    class Cat(Animal):
        def __init__(self, name):
            self.name = name
    
    
    c = Cat("miaomiao")  
    c.eat()        # miaomaio eating sth

        子类若没有构造函数,则使用父类的构造函数,若有,即有两种方式来调用父类的构造函数

    class Animal:
        def __init__(self,age):
            self.age=age
        def eat(self):
            print("%s eating sth" % self.name)
            
    class Cat(Animal):
        def __init__(self, name,age):
            # Animal.__init__(self,age) #first 
            super().__init__(age)       #second
            self.name = name

      抽象类

    四,组合与重用 

       当几个类有着共同的属性时,我们可以将共同的部分抽象出来当做父类,而组合则是一种所有关系,如学校与老师,班级与学生。

    class Student:
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
    class class_grade:
    
        def __init__(self):
            self.li=[]
    
        def put(self,name,age):
             self.li.append(Student(name, age))
    
    c=class_grade()
    c.put("Jack",18)
    print(c.li[0].name,c.li[0].age)  #Jack 18

      五,封装

      封装具有两个特点:

        将属性和方法封装在一个对象中,隐藏细节,仅提供接口;

        具有访问控制;

      第一个特点在前文已经阐述完了,我们来看Python类中的访问控制。

      在Python中并没有真正的限制类的外部或者是子类对类内部数据的访问,而是一种约定,一种隐藏不直接暴露。

      通过双下划线来隐藏

    class Foo:
        __N=2
        def __init__(self):
            self.__name="Jack"
        def func(self):
            print(self.__N)  #0
            print(self.__name) #Jack 类的内部可以直接通过名字访问
    f=Foo()
    f.func()
    # print(self.__name) name #'self' is not defined
    # print(f.__N)     #'Foo' object has no attribute '__N'
    print(f._Foo__N)  #可以通过_类名__变量名 访问 实例属性和函数属性同理  

          这种变形需要注意的问题是:

      1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N,即这种操作并不是严格             意义上的限制外部访问,

      仅仅只是一种语法意义上的变形,主要用来限制外部的直接访问。

      2.变形的过程只在类的定义时发生一次,在定义后的赋值操作,不会变形

      那么我们可以用以下方法来给外部提供一个方法,使类外面对私有变量友好访问

         property(特性)

    class Foo:
        __N = 2
    
        def __init__(self):
            self.__name = "Jack"
    
        @property    #访问
        def name(self):
            return self.__name
    
        @name.setter    #设置值
        def name(self, value):
            if not isinstance(value, str):
                print("请输入字符串类型")
            else:
                self.__name = value
    
        @name.deleter    #删除
        def name(self):
            del self.__name
    
    
    f = Foo()
    print(f.name) #像是调用属性,实则调用方法,也符合实际
    f.name="Bob"
    del f.name

      通过实现不同的函数就能实现不同的访问控制

     六,多态

      我们先回顾一下C++中的多态:父类指针(引用)指向(引用)子类或者父类对象时,会根据实际对象的类型来调用不同的方法。而在python中,由于都是动态数据类型,赋值的时候就是初始化,因此多态更偏向一种代码逻辑而不是语法。

    class demo1:
        def display(self):
            print("这是demo1")
    
    
    class demo2:
        def display(self):
            print("这是demo2")
    
    
    class demo3:
        def display(self):
            print("这是demo3")
    
    
    def func(obj):
        obj.display()
    
    
    if __name__ == '__main__':
        d1 = demo1()
        d2 = demo2()
        d3 = demo3()
        # ---调用同一个函数的不同表现形态--
        func(d1)  # 这是demo1
        func(d2)  # 这是demo2
        func(d3)  # 这是demo3
  • 相关阅读:
    mysql相关
    java注解@Valid@Validated表单验证
    驼峰参数、下划线["_"]参数,属性互传
    redis,windows设置记录
    Java入门第一季学习总结
    计算属性calc()的运算规则
    swiper实现翻页,页面高度超出可滚动
    git常用命令
    Linux下svn常用命令
    图片高度不够一页,如何覆盖全屏
  • 原文地址:https://www.cnblogs.com/ifyoushuai/p/9140256.html
Copyright © 2020-2023  润新知