类与面向对象介绍

1 类与对象(实例)的区别1 1 类的定义类:用来描述具有相同的属性和方法的对象的集合,对某一类具有共同特点的事物的抽象。对象:Python里面 "一切皆对象 "

1 类与对象(实例)的区别

1.1 类的定义

  类:用来描述具有相同的属性和方法的对象的集合,对某一类具有共同特点的事物的抽象。
  对象:Python里面"一切皆对象",对象是类的实例、类的具体化。但Python也支持面向过程。类并不能直接使用,通过类创建出的实例(又称对象)才能使用。
  类名规则:
    ①命名规则遵循”大驼峰式命名”,每个单词的首字母大写。
    ②尽量使用单个或者多个有意义的单词连接而成。
class 类名称(继承关系):
  多个(≥0)类属性...
  多个(≥0)类方法...
不写父类,默认继承object

1.2 类与对象的关系

  1. 类是属性与方法的集合,对象具有类属性和方法的具体事物(就是基于类而创建的一个具体的事物),所以先有类,再有对象。
  2. 类只有一个,但可实例化多个对象。
  3. 不同的对象之间属性值可能会各不相同。
  4. 对象的属性、方法同类的属性、方法。
实例:
以下是一个简单的 Python 类的例子
class Emploee:

    empCount = 0
    companyName = "XX"

    def __init__(self, dmallId, name, position):
        self.dmallId = dmallId
        self.name = name
        self.position = position
        Dmaller.empCount += 1

    def displayEmployee(self):
        print("Name : ", self.name, ", Salary: ", self.position)

    def displayCount(self):
        print("Total Employee: {}".format(Dmaller.empCount))

1.2 属性和方法的定义

  属性:类的静态属性、特征用变量定义,分为成员属性(成员变量)、类属性(类变量)。
  方法:类的行为或动态用函数、方法实现,分为成员方法(动态方法)、类方法(静态方法)
  无论是类属性还是类方法,都无法像普通变量或者函数那样,在类的外部直接使用它们。可以将类看作一个独立的空间,则类属性其实就是在类体中定义的变量,类方法是在类体中定义的函数
  类变量的特点:所有类的实例化对象都同时共享类变量,也就是说,类变量在所有实例化对象中是作为公用资源存在。
  访问方式
    类内部:通过类名cls关键字来访问;
    类外部:通过类名或实例来访问。通过类名不仅可以调用类变量,也可以修改它的值;也可以使用类对象来调用所属类中的类变量(此方式不推荐使用),但无法修改类变量的值。
  注意,因为类变量为所有实例化对象共有,通过类名修改类变量的值,会影响所有的实例化对象。
  定义位置:在类起始处统一定义
    每次实例化新对象时,拷贝一个副本给对象
class System:
    name = "erp系统"
    add = "http://erp.dmall.com"

    def erp(self, content):
        print(content)
if __name__ == '__main__':
    erp = System()
    laike = System()
    System.name = "erp"
    print(laike.name)
    print(System.name)

1.2.2 成员变量/实例变量

  定义:指的是在任意类方法内部,以“self.变量名”的方式定义的变量,其特点是只作用于调用方法的对象。
  定义位置:一般是在构造函数init方法中通过self完成定义,每次实例化就创建,实例结束就销毁。
  访问方式:
    类内部-通过self访问,即成员方法可以使用类变量;
    类外部-通过实例访问,也就是说对象可以访问成员变量。
    但是类不能直接访问成员变量。
 
初始化函数(构造函数)
  作用:python在创建类的实例的时候,会自动调用这个类的init()方法,进行初始化数据。但init函数尽量不要写复杂的逻辑,逻辑代码可用成员方法实现,尽量只是定义对象的共有属性。
  创建实例的时候先看类的构造函数,决定了创建对象的时候传入哪些参数。
  所有的成员变量、方法第一个参数默认是self,但是调用的时候不需要传值。
def __init__(self,args):
    self.args = args  #把创建对象传进来的args存储在当前对象的args里面 

 

self存在原因:
  Python 规定,无论是构造方法还是实例方法,最少要包含一个参数,并没有规定该参数的具体名称,命名为self只是为了代码具有更好的可读性。
  同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法,换句话说,Python 会自动绑定类方法的第一个参数指向调用该方法的对象。如此,Python解释器就能知道到底要操作哪个对象的方法了。因此,程序在调用实例方法和构造方法时,不需要手动为第一个参数传值。
  self是指实际调用该方法的对象,self是个指针,永远指向当前对象自己。
class Person:
    def __init__(self):
        print("正在执行构造方法")
    # 定义一个study()实例方法
    def study(self):
        print(self,"正在学Python")
zhangsan = Person()
zhangsan.study()
lisi = Person()
lisi.study()
  思考点:self一定要写成self吗?self可以不写吗?看参见文档《读懂python中的self》。

1.2.3 局部变量

  除了实例变量,类方法中还可以定义局部变量。和前者不同,局部变量直接以“变量名=值”的方式进行定义,例如:
class Ware:
    def warePrice(self, price):
        sale = 0.8*price
        print("优惠后的价格为:%s" % sale)
    def wareStock(self):
        print(self.sale)
apple  = Ware()
apple.warePrice(10)
  定义局部变量是为了所在类方法功能的实现。需要注意的一点是,局部变量只能用于所在函数中,函数执行完成后,局部变量也会被销毁。
1.2.4 成员方法/实例方法
  通常情况下,在类中定义的方法默认都是实例方法。
class CLanguage:
    def __init__(self):
        self.name = "Dmall"
    # 下面定义了一个say实例方法
    def say(self):
        print("正在调用 say() 实例方法")
  实例方法最大的特点就是,它最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)。实例方法通常会用类对象直接调用,例如:
clang = CLanguage()
clang.say()
  调用方式:
    内部:可以访问成员变量、类变量(self或类名)、成员方法(self)、类方法(self或类名) 。
    外部:通过对应调用 。
  成员方法可以使用类名访问吗?其实是可以的,但此方式需要手动给 self 参数传值。例如:
#类名调用实例方法,需手动给 self 参数传值
clang = CLanguage()
CLanguage.say(clang)

  什么时候定义为成员方法:需要访问成员变量时。

1.2.5 类方法/静态方法

  @classmethod 修饰的方法为类方法;采用 @staticmethod 修饰的方法为静态方法。
 
  类方法
  Python 类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,Python 会自动将类本身绑定给 cls 参数(注意,绑定的不是类对象)。也就是说,我们在调用类方法时,无需显式为 cls 参数传参。
  和 self 一样,cls 参数的命名也不是规定的(可以随意命名),只是 Python 程序员约定俗称的习惯而已。
  
class CLanguage:
    def __init__(self):
        self.name = "Dmall"
    # 下面定义了一个类方法
    @classmethod
    def info(cls):
        print("正在调用类方法", cls)

  注意,如果没有 @classmethod,则 Python 解释器会将 info() 方法认定为实例方法,而不是类方法。

  类方法推荐使用类名直接调用,当然也可以使用实例对象来调用(不推荐)。例如,在上面 CLanguage 类的基础上,在该类外部添加如下代码:
#使用类名直接调用类方法
CLanguage.info()
#使用类对象调用类方法
clang = CLanguage()
clang.info()

 

  静态方法

  静态方法,其实就是我们学过的函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。
  静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。也正因为如此,类的静态方法中无法调用任何类属性和类方法。
  静态方法需要使用@staticmethod修饰,例如:
class CLanguage:
    @staticmethod
    def info(name,add):
        print(name,add)
 
  静态方法的调用,既可以使用类名,也可以使用类对象,例如:
class CLanguage:
    @staticmethod
    def info(name, add):
        print(name, add)
#使用类名直接调用静态方法
CLanguage.info("erp系统", "http://XXX.com")
#使用类对象调用静态方法
clang = CLanguage()
clang.info("erp系统", "http://XXX.com")