面向对象二 成员 嵌套

     成员

一类的成员

  1.变量(字段)

  字段包括:实例变量(普通字段)和类变量(静态字段),他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同.

准则:
  实例变量(字段)访问时,使用对象访问,即: obj1.name
  类变量(静态字段)访问时,使用类方法,即: Foo.country (实在不方便时,才使用对象)

 知识点一: 什么时候用类变量?
  当所有对象中有共同的字段时且要改都改要删都删时,可以实例变量(字段) 提取到 类变量(静态字段)

class Province:
    # 静态字段(类变量)
    country = "中国"
    def __init__(self,name):
        # 普通字段(实例变量)
        self.name = name
#直接访问普通字段
obj = Province("北京省")
print(obj.name)
#直接访问静态字段
Province.country
#结果:北京省

  实例变量(普通字段)属于对象

    公有实例变量(字段)

    私有实例变量(字段)

  静态字段属于

    公有类变量(静态字段)

class C:
    name = "公有静态字段"
    def func(self):
        print(C.name)
class D(C):
    def show(self):
        print(C.name)
C.name   #类访问
obj = C()
obj.func() # 类内部可以访问
obj_son = D()
obj_son.show()   #派生类中可以访问
 #结果:公有静态字段

    私有类变量(静态字段)

class C:
    __name = "公有静态字段"
    def func(self):
        print(C.__name)
class D(C):
    def show(self):
        print(C.__name)
C.__name     #类访问        ==>错误
obj = C()
obj.func()    #类内部可以访问    ==>正确
obj_son = D()
obj_son.show()   #派生类中可以访问    ==>错误
#结果:公有静态字段

  静态字段在内存中只保存一份

  普通字段在每个对象中都要保存一份

应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段

#无法访问
class Base(object):
#私有实例变量(私有字段)
__secret = "受贿" class Foo(Base): def func(self): print(self.__secret) print(Foo.__secret) obj = Foo() obj.func() # 无法访问 #结果:报错 #可以访问 class Base(object): __secret = "受贿" def zt(self): print(Base.__secret) class Foo(Base): def func(self): print(self.__secret) print(Foo.__secret) obj = Foo() obj.zt() #结果:受贿

  2.方法

方法包括:实例方法(普通方法)、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

  普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self

class Foo(object):
    def __init__(self,name):
        self.name = name
        #实例方法
    def func(self):
        print(self.name)
obj = Foo("wang")
obj.func()
#结果:wang

  静态方法:由调用;无默认参数;

class Foo(object):
    def __init__(self,name):
        self.name = name
    #静态方法,如果方法无需使用对象中封装的值,那么就可以使用静态方法
    @staticmethod
    def display(a1,a2):
        return a1 + a2
set = Foo.display(1,3)
print(set)
#结果:4

总结
  1. 编写时:
    - 方法上方写 @staticmethod
    - 方法参数可有可无
  2. 调用时:
     - 类.方法名() *
     - 对象.方法名()
  3. 什么时写静态方法?
     - 无需调用对象中已封装的值.

  类方法:由调用; 至少一个cls参数;执行类方法时,自动将调用该方法的复制给cls

class Foo(object):
    #类方法,cls是类
    @classmethod
    def show(cls,x1,x2):
        print(cls,x1,x2)
Foo.show(1,8)
#结果:<class '__main__.Foo'> 1 8

 总结
  1. 定义时:
       - 方法上方写: @classmethod
    - 方法的参数: 至少有一个cls参数
  2. 执行时:
    - 类名.方法名() # 默认会将当前类传到参数中.
  3. 什么时用?
    - 如果在方法中会使用到当前类,那么就可以使用类方法.

相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。

不同点:方法调用者不同、调用方法时自动传入的参数不同。

  3.属性(通过方法改造出来)

class Foo(object):
    def __init__(self):
        pass
    @property
    def start(self):
        return 1
    @property
    def end(self):
        return 10
obj = Foo()
print(obj.start)
print(obj.end)
#结果:1      10

 总结:

  1.编写时

    方法上写@property

    方法参数:只有一个self

  2.调用时:无需加括号   对象.方法

  3.应用场景:对于简单的方法,当无需传参且有返回值时,可以使用@property

二.嵌套(建模)

面向对象

class School(object):
    def __init__(self,name,address):
        self.name = name
        self.address = address
    def speech(self):
        print("讲课")
obj1 = School('老男孩北京校区', '美丽富饶的沙河')
obj2 = School('老男孩上海校区', '浦东新区')
obj3 = School('老男孩深圳校区', '南山区')
class Teacher(object):
    def __init__(self,name,age,salary):
        self.name = name
        self.age = age
        self.__salary = salary
        self.school = None
t1 = Teacher("李杰",19,158888)
t2 = Teacher("雁涛",18,582)
t3 = Teacher("alex",18,188888)
t1.school = obj1
t2.school = obj2
t3.school = obj3
print(t1.school.name)
print(t1.school.address)
print(t1.name)
print(t1.age)
t1.school.speech()
#结果: 老男孩北京校区
#     美丽富饶的沙河
#     李杰
#     19
#     讲课

  准则: 字段和方法的归类.

原文地址:https://www.cnblogs.com/chenxi67/p/9549424.html