1.python中的类和对象的概念
1.1 类也是对象
- 在python中的一切皆对象 ,所以python中的类 也是对象。
这与c++是不同的,c++的类在实例化为对象之前是没有意义的,编译器也不会为其分配内存。
- python中的类 即使不实例化为对象,也可以单独使用。
- 类 是一种 对象 所以类可以拥有属于自己的定义 方法 和 属性。
1.2 类的定义示例
如下是一个类的示例,大家可以先看一下这个类,对于语法在此不过多描述,这个类包含如下元素:
- python中所有的类都继承 object 类
class Person(object): # 显示的说明这个类继承object类 class Person: # 没有指定父类,即使没有写,这个类也默认继承 object 类
- 公有/私有 类 属性/方法
- 公有/私有 对象 属性/方法
- 公有/私有的静态方法
- 对象的构造方法 _init_
- 在 例化对象时自动调用, 用于 绑定 或 初始化 对象属性。
- _init_ 是一种特殊的写法,叫这个名字的就是构造方法
- 公有/私有的概念,类似与 c++中的 private/public
- python中的 属性/方法 的名称以 双下划线 __ 开始,则这个 属性 或者方法即为 私有的。
class Person(object):# 公有的类属性,这个属性是属于类的,# 公有属性于c++中的public变量,可以通过类名访问这个属性species = "人类"# 私有类属性,这个属性是属于类的。# 私有属性类似于c++中的private变量,只能在类方法中使用,外部不能访问。__class_private_attr = "这是私有类属性,只能在类方法中使用"# 构造方法,类似c++的构造函数,在例化对象时自动调用def __init__(self, name, age):# 公有对象属性,这些属性是属于对象的的。# 公有属性于c++中的public变量,可以通过属性名访问这个属性self.name = nameself.age = age# 私有对象属性# 私有属性类似于c++中的private变量,只能在对象的方法中使用。self.__private_attr = "这是私有对象属性,只能在对象的方法中使用"# 公有类方法,类方法定义需要使用修饰器@classmethod@classmethoddef get_species(cls):return cls.species# 私有类方法,类方法定义需要使用修饰器@classmethod@classmethoddef __get_class_private_attr(cls):return cls.__class_private_attr# 公有对象方法def introduce(self):print(f"大家好,我是{self.name},今年{self.age}岁。")# 私有对象方法def __private_method(self):print("这是私有对象方法")# 公有静态方法@staticmethoddef is_adult(age):return age >= 18# 私有静态方法@staticmethoddef __is_child(age):return age < 18# 创建对象
person = Person("张三", 25)# 访问公有对象属性
print(person.name) # 张三
print(person.age) # 25# 尝试访问私有对象属性(会报错)
# print(person.__private_attr)# 调用公有对象方法
person.introduce() # 大家好,我是张三,今年25岁。# 尝试调用私有对象方法(会报错)
# person.__private_method()# 访问公有类属性
print(Person.species) # 人类# 尝试访问私有类属性(会报错)
# print(Person.__class_private_attr)# 调用公有类方法
print(Person.get_species()) # 人类# 尝试调用私有类方法(会报错)
# print(Person.__get_class_private_attr())# 调用公有静态方法
print(Person.is_adult(25)) # True
print(Person.is_adult(16)) # False# 调用私有静态方法(会报错)
# print(Person.__is_child(10))
2.类的属性/方法, 对象的属性/方法, 和静态方法的关系
2.1 类属性和对象属性
- 类属性是属于类本身的,所有对象共享这些属性(对象对类属性只能读不能写)。
- 通过 类名 访问 类对象 是可读可写的。
- 通过 对象名 访问 类对象是只能读不能写的,并且如果对象有同名属性,会遮蔽 类属性。
- 如果通过 对象名 修改 类对象,则会创建并绑定一个同名的 对象属性,然后 同名的 对象属性 会屏蔽类属性。
- 对象属性是属于每个对象独有的。
- 对象属性只有在实例化时才会被绑定,在此之前是不存在的,对象属性只能通过对象名访问,不能通过类名访问。
2.2 类方法和对象方法
- 类方法 的第一个参数是 类对象,一般使用 cls 命名, 类似与c++中的this指针,始终指向类对象 。
- 类方法 可以通过 类名 或者 对象名 进行访问。
- 类方法 中可以访问 类属性 和 类方法 。 但不能访问 对象方法 和 对象属性 的。
- 对象方法的第一个参数是 对象本身 , 一般使用 self 命名代表当前对象,类似与c++中的this指针,始终指向对象本身。
- 对象方法 只能通过 对象名 调用, 不能通过类名调用。
- 对象方法 中可以访问 对象属性 ,对象方法 , 类属性 , 类方法
2.3 静态方法
- 静态方法不需要cls或self参数,可以独立存在。
- 静态方法可以通过类名或对象名调用。
- 静态方法更像是一个定义在类作用域中的普通方法。
2.4 理解总结
- 我们可以站在时间的角度理解 类对象属性/方法 ,静态方法 ,对象的属性/方法。
- 类也是一种对象,在定义类的的时候 类对象属性/方法 ,静态方法 就已经被创造了。
- 在例化对象的时候对象的属性/方法才会被创造
- 类对象属性/方法 ,静态方法 在时间上是先于 类对象属性/方法 的,
- 所以通过 类名 是不能访问 对象属性/方法 的,类方法 也不能访问 对象方法/属性,因为这个时候 对象方法/属性 还没有被创造。
- 在对象被创造的时候,类一定被创造了,所以可以通过对象名访问属于 类的属性/方法 静态方法。
3. 类的继承
3.1 类的继承示例
class Parent1(object):def parent1_func(self):print("parent1_func")class Parent2(object):def parent2_func(self):print("parent2_func")class Son(Parent1, Parent2):def son_func(self):print("Son_func")son = Son()son.parent1_func()
son.parent2_func()
3.2 类继承
类继承的语法参见 3.1 的例子,对于类继承,记住下面三点即可
- 所有的类默认继承自 object 类
- 子类可以使用父类的方法和属性
- 如果子类由同名的方法和属性,则会屏蔽父类的方法和属性;换句话说,自类可以重写父类的方法和属性