• 面向对象---成员,嵌套(建模)


    上一篇面向对象文字介绍了面向对象基本知识:

    ①面向对象是一种编程方式,此编程方式的实现是基于类和对象的使用

    ②类是一个模板,模板中包装了多个'函数'供使用(可以讲多函数中公用的变量封装到对象中)

    ③对象,根据模板创建的实例(即:对象),实例中用于调用被包装(封装)在类中的函数

    ④面向对象的三大特性:封装,继承和多态

    本片讲介绍python类的成员,以及成员修饰符,类的特殊成员

     类的成员                                                                                                                    

     类的成员可以分为三大类:字段,方法和属性

     

    注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份。

    class Foo:
        # 方法
        def __init__(self, name):
            # 实例变量/字段
            self.name = name
    
        # 方法
        def func(self):
            pass
    
        # obj,Foo类的对象
    
    
    # obj,Foo类的实例
    obj = Foo('赵瑞鑫')
    类的成员

     上面的代码中__init__和method都属于类的方法,又称实例方法.总之这样的东西需要用对象来方法,二上面的self.属性1 = 参数1 这个代码的含义是给对象设置属性信息.含义是这个对象的xxx属性是xxxx,这个东西又被成为成员变量或者实例变量,再或者被成为字段,都是一个意思

    一,成员分为三类

     类的成员:变量

    1.实例化变量(字段)

    2.类变量(静态变量)

    先说什么是实例变量,说白了就是每个实例都应该拥有的变量,比如人的名字,爱好,每个人的个人信息都属于实例变量,那什么是类变量,比如在座的都是中国人,那大家都拥有一个国家比如:

    class Foo:
        contry = '中国'#;类变量(静态字段)
        def __init__(self,name):
            self.name = name#实例变量(字段)
    
        def func(self):
            pass
    
    obj_1 = Foo('小白')
    obj_2 = Foo('后福')
    变量和类的关系
    class Person :
        country = "中国" #类变量,表示所有的该类都在共享这个变量
        def __init__(self,name,num)
        #实例变量(字段)表示你创建的每一个人都有这三个变量
        self.name = name
        self.num = num
    p1 = Person("alex",10086)
    print(p1.name) # alex
    print(p1.country)  #中国
    
    p2 = person("wusir",10010)
    print(p2.name)   #wusir
    print(p2.country)  #中国

    我们发现对象p1和p2的name都是对象自己的,但是country是类的,大家公用同一个变量.如何来验证呢?

    Person.country = '大清'  #在这里,把国家改成了大清
    p1  =Person("alex",10086)
    print (p1.name)
    print (p1.country)  #alex是大清的
    
    p2 = Person("wusir",10010)
    print(p2.name)
    print(p2.country)  #wusir也是大清的

    发现了吧,如果把类变量中的值改了,大家看的也会跟着变了,为甚?我们要从内存来分析:

    通过图我们可以发现,实例变量中都隐含着一个创建这个对象的类,通过这个类就能找到我们类中定义的全部内容,包括方法和属性信息等等....

    p1 = Person("alex",10086)
    p1.country = "大清"
    print(p1.name)
    print(p1.country)  #大清
    
    p2 = Person("wusir",10010)
    print(p2.name)
    print(p2.country)  #中国

    上面是大清,下面是中国,为什么?

    注意在执行p1.country= "大清"的时候,其实并没有去改变类中的country,而是给对象添加了一个实例变量,只有当前的p1是存在的,p2 是不存在的

     在图上我们可以看到,其实我们并没有去改变变量,只是在p1中添加了一个实例变量,仅此而已,通过这里,我们应该可以发现,类变量最好用类名来访问,当然我们通过对象名也可以访问,但是只能看,不能改变.

    案例:通过程序来记录当前类被创建了多少个对象?

    好了,我们来小的总结:

    实例变量,给对象用的

    类变量,多个对象共享的,最好用类名来访问,这样更加规范

     二,类的成员:方法

    1.成员方法(实例方法)

    2.静态方法

    3.类方法

    先说第一个成员,我们用的最多的就是这个,昨天写的代码中所有的方法都可以被称之为成员方法,说白了就是对象直接访问的方法叫做成员方法.

    class Computer:
        #实例方法(成员方法)
        def play(self):
            print("我的电脑可以玩儿")
    c = Computer()
    c.play()  #对象直接去调用实例方法

    静态方法,静态方法不需要我们给方法传递self,也就是说,当出现一个方法不需要使用到成员变量的时候,就可以选择使用静态方法,静态方法需要我们在方法上面添加一个@staticmethod

    @staticmethod
    def fare():
        print("我的电脑很厉害,可以炒饭")

    静态方法和静态变量一样,一般都是使用类名直接访问和调用的.

    Computer.fare() #类名可以直接访问
    c.fare()  #对象可以访问,但最好不要这么干,以便于区分静态方法和实例方法

    类方法,类方法和静态方法差不多,只不过类方法需要在参数列表中的第一个位置预留一个位置,通常我们给一个参数起名字叫cls.类方法在被调用的时候也不需要传递实例对象.但是,系列会自动的把类传递给一个参数,类方法在编写的时候,需要在类方法添加一个@classmethod

    class Computer :
        def play(self) :
            print("我的电脑可以玩游戏")
        @staticmethod
        def fare():
            print("我的电脑很厉害,可以炒鸡蛋")
        
        @classmethod
        def cal(cls,a,b)
            print(cls)
            return a+b
    print(Computer.cal(1,2))#此时会自动把类名传递给类方法的第一个参数

    三,类的成员--属性

     属性其实就是通过方法改造过来的一种变量的写法,在方法上添加一个@project就可以了

    如果你执行obj.func()的话,obj就去Foo里面找self如图所示

    对象和类之间的关系

    class Person:
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
              
           @property    
            def age(self):
                return 1
    p =Person()
    age = p.age
    print(age)

    应用场景:我们一般保存数据的时候,不会保存一个人的年龄,因为随着时间的推移.每个人的年龄都时刻在改变着,那么如何保存更加完美呢?很简答,保存出生年月日,然后通过程序来计算,你当期的年龄,实时的那这个时候就应该进行相应的计算了,而计算属于一个功能.当然要写在方法里面了.但是对于年龄这个属性而言 他应该是一个数值,而不是动作,所以python就提供了这样一种机制.通过方法来描述一个属性.

     注意:

    1.方法参数只有一个self

    2,方法上方要写@property

    3.调用的时候,我们不需要写括号,直接当成属性变量来用就可以了

    4.这种套路只能取值,不能设置值

    四,私有

      在python中,一般人不提倡设置和使用私有信息的,但是有些场景不得不这样做,比如在公司.每个人的收入情况,这种内容是绝对不能公开的,还有你的老婆也是私有的,只能你一个人使用,别人不能碰,碰了就炸了锅..

      在python中使用_作为方法或者变量的前缀,那么这个方法或者变量就是一个私有的

      1.私有变量

    class Person:
        def__init__(self,laopo,mimi):
            self.__laopo = laopo  #私有的
            self.__mimi = mimi
    
    alex = Person("wusir","他们在一起了")
    print(alex.__mimi)  #私有的谁也不可以动

    这样的话程序报错,私有的内容是访问不到的,但是这个访问不到的是有一定的局限性的.比如:

    class Person:
        def __init__(self,laopo, mimi):
            self.__laopo = laopo
            self.__mimi = mimi
    
        def gaosuni(self):
            print("大喇叭开始广播了")
            return self.__mimi  #私有的内容在他那里,他是可以随意使用的
    
    alex = Person("wusir","他们俩在一起了")
    mimi = alex.gaosuni()  #通过一个非私有的方式,访问到了他的秘密
    print(mimi)

      记住,私有的内容不能直接访问,但如果对方开辟了外界访问的通道(公共方法).那可以通过这个公共的方法来获取到私有的内容,这样做的好处是外界只能看,但是改不了.不单单实例变量有私有的,类变量(静态变量)一样拥有这样的属性:

    class Person:
        __zisi="人都是自私的" #人都是自私的,但是这个自私不希望别人知道
        def __init__(self,laopo, mimi):
            self.__laopo = laopo
            self.__mimi = mimi
         def gaosuni(self):
            print("大喇叭开始广播了")
            return self.__mimi
    alex = Person("wusir","他们俩在一起了")
    mimi = alex.gaosuni()  #通过一个非私有的方式,访问到了他的秘密
    print(mimi)
    print(Person.__zisi)#报错

    2.私有方法

      私有方法,只能自己访问的方法.别人都不能随便调用,这个很好理解  就是你和你女朋友来约会 你会希望别人来调用吗?

    class Person :
        def __init__(self):
            pass
        def __yue(self):
            print("我要约会")
        def job(self):
            print(我要工作)
    
    p = Person()
    p.__yue()  #报错
    p.job()

    __yue是一个私有的方法,只能在类中调用自己  类在外面不能访问

    job是一个成员方法,并且是一个开放的方法,在类外界可以访问到同样的  类中的私有方法也是相对而言的  我们可以通过其他方法来方法文这样的方法,.

    class Person:
        def __init__(self):
            pass
         def __yue(self):
            print(""我要约会")
          def job(self):
                print("我要工作") #在自己类中访问自己的其他方法,哪怕是私有的,也是自己在用
    
    p = Person()
    p.job()

    关于类方法和静态方法,和成员方法一样,就不赘述了

    但是需要注意的是,对于私有的内容而言,子类是无法继承的

  • 相关阅读:
    JVM全面分析之程序计时器
    JVM全面分析之类加载系统
    问题
    -----------------------算法学习篇:斐波拉契数列------------------------
    -----------------------------------A Tour of C++ Chapter8-------------------------------------------
    -----------------Clean Code《代码整洁之道》--------------------
    -----------------------------------A Tour of C++-------------------------------------------
    -----------------Clean Code《代码整洁之道》--------------------
    http响应状态码大全
    DOM之通俗易懂讲解
  • 原文地址:https://www.cnblogs.com/zhaodingding/p/9550429.html
Copyright © 2020-2023  润新知