面向对象技术的基本概念
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。简单来说,类是模板,而实例则是根据类创建的对象
- **类变量:**类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- **实例变量:**定义在方法中的变量,只作用于当前实例的类。
- **数据成员:**类变量或者实例变量用于处理类及其实例对象的相关的数据。
- **方法:**类中定义的函数。
- **实例化:**创建一个类的实例,类的具体对象。
- **对象:**通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
- 封装:将多个方法或者是属性放在一个私有类之中,而这个私有类不会被其他对象所访问。
- **继承:**即一个派生类(derived class)继承基类(base class)的字段和方法。
继承允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个 Dog 类型的对象派生自 Animal 类,所以 Dog 也是一个 Animal。 - **方法重写:**如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 多态:不同对象,调用同符类的同一个方法,表现出不同的形式。
继承、封装、多态是面向对象的三大特性。类能够实现面向对象三大特性。
和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。
Python 中的对象
- 对象是 Python 中最基本的概念之一,在 Python 中,万物皆可对象。
Python 将所有的数据都作为对象来处理,赋值语句会在内存中创建对象和变量。 - 对象有三个基本属性:即类型、身份标识、值
print(type(500)) # 输出:<class 'int'> # 对象的类型 print(id(500)) # 输出:2556827724176 # 对象的身份标识 print(500) # 输出:500 # 对象的值
类的定义
简述
python 中虽然任何一个变量都可以被称之为对象,但是实际上的对象是对类属性和方法的具体实例化,使用类才能创建出真正意义上的对象。
Python 中,类通过 class 关键字定义,类名通用习惯为首字母大写。
- 定义一个类的基本格式:
class 类名(父类): pass # 此处可添加属性和方法 class 类名: pass # 此处可添加属性和方法
注:
- Python3 默认所有的 class 都隐式地继承 object 类,故 Python3,建议不必显式地继承 object
- python 中的内部类,python 的内部类不但可以定义在类中,也可以定义到方法中
类的属性
分为类属性与实例属性两种:
- 类属性:绑定在类上的属性,有且只有一份,每个实例都可以访问的共有属性
- 类属性可以直接通过类来调用,也可以通过类的实例化对象来调用,类似于 Java 中的静态常量
- 注意:python 中通过类的实例化对象更改类的属性的值,并不会修改类变量的值!
因为通过实例修改类的属性实际是先给实例创建了一个与类属性同名的实例属性,然后修改的实例属性,实例属性访问优先级比类属性高,所以访问时优先访问实例属性,它将屏蔽掉对类属性的访问
class Person: name = 'aaa'; person = Person() print(person.name) # 输出:aaa person.name = "bbb" print(person.name) # 输出:bbb print(Person.name) # 输出:aaa del person.name # 可以使用 del 删除与类属性同名的实例属性 print(person.name) # 输出:aaa
- 实例属性:每个实例都各自拥有,相互独立访问实例属性:
- 在实例方法的内部,通过 “self.属性名”
- 在类外,通过调用实例方法的间接方式访问
- **私有实例属性:**属性名使用一个下划线开头(
_private_attrs
),,表示声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用方式为:self._private_attrs
类的方法
在类的内部,使用 def 关键字来定义函数,类中定义的函数又称之为方法。
- 类方法:
在 python 中,类方法是装饰器 @classmethod 修饰的方法,表示这是一个类方法
类方法的第一个参数为 cls,表示类本身。这使得类方法可以访问和修改类属性和其他类方法。
类方法可以直接通过类来调用,也可以通过类的实例化对象来调用(不推荐)
子类继承性:子类可以继承并覆盖父类的类方法。 - 实例方法:与一般函数定义不同,实例方法的第一个形参必须是 self,self 在这里的含义是指实例化的对象。注:self 并不是 python 中的关键字,所以实例方法的第一个形参实际也可以是其他名字,但是行业惯例都将其命名为 self调用实例方法:
- 在实例方法的内部,通过 “self.方法名()”
- 在类外,通过 “对象名.实例方法名(除 self 的参数)”
- 静态方法:
装饰器: 静态方法使用 @staticmethod 装饰器进行定义。
参数: 静态方法没有特殊的参数,不需要引用类本身或实例。它们类似于普通函数。
不能访问类属性和方法: 静态方法不能直接访问类属性和方法,因为它们没有传递类或实例作为参数。
实例化对象不是必需的: 可以通过类本身调用静态方法,而不需要实例化对象。例如,MyClass.my_static_method()
子类不继承性: 静态方法不会被子类继承,因为它们与类或实例无关。
常用场景: 静态方法通常用于与类相关但与特定实例无关的操作,例如实用函数或辅助函数。 - 私有方法:
方法用两个下划线开头(__private_method
),表示声明该方法为私有方法,不能在类地外部调用。
在类的内部调用方式为:slef.__private_methods
类的特殊函数
主要有以下几种:
__init__
(初始化函数):在调用类去创建对象时会自动调用,用来完成对对象的初始化。
python 中的初始化函数不支持方法的重载,有且仅有一个
python 中可以通过**map
将初始化函数定义为灵活的多参数传递
class TestClassA: def __init__(self, a, b): print("我是python的构造方法"); class TestClassB: #定义灵活的可传递任何数据的构造方法 def __init__(self, **map): print("我是python的构造方法" + map.get("name")); print("我是python的构造方法" + map.get("age"));
- 拓展:
__init__
方法的用法类似 java 中的构造方法,但它不是构造方法,Python 中创建实例的方法是__new__
,这个方法在 python 大多数使用默认方法,一般不需要重新定义 __del__
(析构函数):在对象被回收时会自动调用
构造函数和析构函数在类的定义时都可以不写
类的继承
- 单继承
语法:
class <类名>(父类名) <语句>
- 示例:
class Student(people): grade = '' def __init__(self,n,a,w,g): #调用父类的构函 people.__init__(self,n,a,w) self.grade = g #覆写父类的方法 def speak(self): print("%s is speaking: I am %d years old,and I am in grade %d"%(self.name,self.age,self.grade)) s = Student('ken',20,60,3) s.speak()
- 类的多重继承
语法:
class 类名(父类1, 父类2, ...., 父类n) <语句1>
- 注意:圆括号中父类的顺序。若是父类中有相同的方法名,而在子类使用时未指定,python 从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法