类的基本构成与实例化

1. 类名:

1.1 命名方式:class 类名:
1.2 类继承:class 类名(父类):

2. 类变量:

2.1 概念:类变量表示类的属性,在整个实例化的对象中是公用的,定义在类中且在函数体之外,通常不作为实例变量使用,实例化时也被传给对象;
2.2 访问方式:名类.变量名或对象.变量名。

3. 构造函数:

3.1 概念:构造函数是用于初始化类的静态属性,即主要用于定义这个类有哪些静态属性(有什么特点),并定义相关静态属性参数名称,当然还有一些功能你在实例化时就执行,你也可以在这里定义;
3.2 定义方式:用一个特殊方法init(self, 参数) 定义类的属性,在类实例化时该方法会被自动执行(如:自动完成输入的参数值传给对象的各个参数),无需做任何调用操作;
3.2.1 self:是类函数放在第一个位置的必有的一个额外参数, 代表的是类的实例对象,self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的,只是习惯用self罢了;
3.2.2 实例变量:self.参数:是绑定到一个实例上的变量,在实例化时,可以在参数位输入值,而且无需任何调用就将这些属性值传递给对象,可以覆盖类变量,
3.2.3 访问方式:在类内部用 self.变量名,在类外部用 对象名.变量名
3.2.4 实例变量与类变量的区别,案例详见:ex41c.py

class A(object):
    va = 10                 # 类变量,它是一个类的全局变量,是所有对象所共享的,它可以被重写(见第19行),在实例化时也重写覆盖(见第11行)
                            # 在外类外部 类名.类变量 或 对象.类变量 访问,在类内部用 self.类变量 访问

    def foo(self):
        print (A.va)        # 类变量va(A.va)等于10,输出10
        print (self.va)     # 实例变量av(self.va)在没有被重写前其值就是类变量va(A.va)的值,self.va = A.va = 10(),输出10

        self.va = 40        # 重写实例变量va(self.va),它会将类变量va(A.va)覆盖,其实例变量va(self.va)等于40;
                            # 这里注意,当进行实例时,实例对象的va(self.va)等于覆盖后的值40,但不是真正意义上改类变量va(A.va)等于40,这一点很重要!!
        print (A.va)        # 类变量va(A.va)还是没变,A.va = 10,输出10
        print (self.va)     # 实例的变量va(self.va)依然上面一样等于 40,输出40 (见第11行同)

        va = 18             # 局部变量va = 18,是方法foo()下的一个局部变量,跟外面的类变量va(A.va)没有任何关系,不是同一个东西!!
        print (va)          # 输出局部变量 18

        A.va = 15           # 重写类变量,类变量va(A.va)由10变成15,是真正意义上把类变量va(A.va)给改写了,就是运行完foo()后,类变量va(A.va)就变成15!!
        print (A.va)        # 重写后的类变量va(A.va)等于15,输出15,
                            # 这是注意了,类变量va(A.va)被改后,如没有再次给obj1实例化,那么实例变量va(self.va)还是以前的值 self.va = 40
        print (self.va)     # 所以,实例变量va(self.va)还是以前的值 self.va = 40,输出40 (与第14行同)


obj1 = A()
obj2 = A()
obj1.foo()                  #执行结果:10    从内部调用执行
                            #         10
                            #         10
                            #         40
                            #         18
                            #         15
                            #         40
# 注意:在运行完 obj1.foo()方法以后,类变量va(A.va)就该方法由10改成15了;

print (A.va)                #执行结果:15  从外部访问类变量va(A.va),执行完foo()函数,类变量va(A.va)已由10改写成15(见19行)
print (obj1.va)             #执行结果:40  从外部访问实例对象obj1的变量va(obj1.va),实例变量va(self.va)还是以前的值 self.va = 40,输出40 (与第22行同)


print (obj2.va)             #执行结果:15  从外部访问对象obj2的变量va(obj2.va),因为上面运行完一次foo()函数后,类变量va(A.va)由10改写成15(见第19行)
                            #被改写后,没有再运行foo()函数,所以类变量va(A.va)等于15没变,输出15!

以下是要注意的几点:

 因为foo()方法不是构造函数__init__(),所以实例化 obj2 = A() 后,foo()方法并没有被自动执行的;
 如果我们把print (obj2.va)代码放到foo()前面去执行,那么它输出的就不是15了,而是修改前的10,不信你可以试试!!
 像第47行,这样的类变量尽量避免重写,因为一旦重写后,由这个类所创建的对象将全部被修改,导致各种不料的后果!!

4. 方法

4.1 类的实例方法:
4.1.1 概念:方法用于定义类的实例的动态属性,即用于定义这个类的实例有哪些功能(能干什么),它可以对静态属性做一些操作,也可独自执行一下任务,它必须通过对象被调用后才会被执行,调用方式:对象名.方法;
4.1.2 定义方式:定义在类里,第一个参数是self,是通过的对象的名称进行调用,在实例化时会将该方法传给对象;
4.2 类的方法:
4.2.1 概念:方法用于定义类的动态属性,即用于定义这个类有哪些功能(能干什么),它可以对静态属性做一些操作,也可独自执行一下任务,它必须通过类名调用,调用方式:对象名.方法;
4.2.2 定义方式:定义在类里,参数没有self,通过类名称进行调用,但在实例化时不会将该方法传给对象;
这个两概念一定要搞清楚!!

5. 类的实例化:

5.1 实例化:创建一个类的实例,类的具体对象(如:猫类的“小黑”,狗类的“旺财”,学生类的“张三”),并把类的相关实例属性与方法传递给对象,同时还可以按一定的位置顺序对参数进行赋值。
5.2 访问方式:实例化后,可以 对象名.属性名 的方式进行访问对象属性变量,也可以 对象名.方法 的方式调用对象的方法;
5.3 注意:类的实例方法可以被传给对象,但类的方法不会被传递!
5.4 类的基本构造及实例化的案例:
案例详见:ex41a.py

class people:   #定义一个people类
    name = 'Human'   #定义类变量(全局属性)
    na = 'Hu'         #定义类公有属性变量
    def __init__(self, n , a, w):    # 定义类的构造函数,用于初始化类的属性,即用于表述这个类有哪些属性,并定义相关属性参数名称
                                     # 这里的self代表的是类的实例对象,表示这个类的对象也有name,age,weight属性
                                     # 构造函数,一旦被实例化了,就马上自动被执行了,无需任何调用
        self.name = n                # 定义类的实例变量name,可在参数n位置的传值,可以覆盖类变量,如name
        self.age = a                 # 定义类的实例变量name,可在参数a位置的传值
        self.weight = w              # 定义类的实例变量name,可在参数w位置的传值
        Nw = w-20                    # 构造函数中,也可以定义一些功能,一般用于做属性参数的计算,然后再调用它的计算结果
        self.Nextyearweight = Nw     # 定义类的实例变量Nextyearweight,其值可以通过一定运算后得到
        print(f"我后年的目标体重是{self.Nextyearweight}斤!")  # 实例化后,这行代码就被自动执行了!

    def Nextyear1(d):      # 定义一个类的方法(注意:不是实例方法,参数也没有self),可以通过类进行调用,不可以通过实例对象进行调用
        Nextw = people.weight - d   # 因为是类方法,所以它也只能访问类变量,不能访问实例变量
        return Nextw    # 返回计算后的结果给调用者

    def speak(self, lw):             # 定义类的方法(功能函数),即用于表述这个类有什么功能,即它可以静态属性做一些操作,也可以独立实现一些操作
                                     # 功能函数,它只有被实例化后,通过对象以 对象名.方法  方式调用才能执行
        print("{}说: 我今年{}岁,体重{}斤哦!".format(self.name, self.age, self.weight))   # 方法speak()可以把按我们要格式把属性打印出来
        N_w = self.weight - lw       # 方法speak()可以将类的属性及其自己参数做一些运算
        print(f"I want to lose weight,next year my weight will be {N_w}!")  # 方法speak()可以将运算结果打印出来
        print("I can do many thing!!")  # 方法speak()可以做一些跟属性没有任何相关的操作

print("We all belong to ",people.name) # 直接调用people类的全局属性name,此时它还没有被覆盖,其值依然是'Human'

print(f"Next year,my weight will be {people.Nextyear1(10)}!")   # Nextyear1(10)类普通属性方法,类外部的函数可以通过类进行调用

Weijp = people("Weijp", 39, 144)      # 用poeple类实例化(创建)一个具体的对象(一个具体人weijp,这个人有poeple类所有的属性和方法)
                                      # 实例化创建weijp对象后,__init__()马上被自动执行,将传值"Weijp", 39, 144马分别传给对象的参数(n , a, w)
Weijp.speak(10)                       # 调用对象(weijp这个人)的speak()函数,还给speak()的参数lw赋值10,然后执行该函数

print(f"My name is {Weijp.name}!")    # 调用weijp对象的name属性,对象的name属性已被重写,其值是"Weijp"
print(Weijp.na)                       # 类变量是可以通过对象.属性名 进行访问

你可能感兴趣的:(类的基本构成与实例化)