传统的结构化设计方法的基本点是面向过程,系统被分解成若干个过程。而面向对象的方法是采用构造模型的观点,在系统的开发过程中,各个步骤的共同的目标是建造一个问题域的模型。在面向对象的设计中,初始元素是对象,然后将具有共同特征的对象归纳成类,组织类之间的等级关系,构造类库。在应用时,在类库中选择相应的类
面向对象编程的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙一个事物在整个解决问题的步骤中的行为
类和对象的主要区别:
对象是类的一个实例,类是一个模板,它描述一类对象的行为和状态
面向对象的三大特征:
1、封装
两层含义:一层含义是把对象的属性和行为看成一个密不可分的整体,将这两者“封装”在一个不可分割的独立单元(即对象)中;另一层含义指“信息隐藏”,把不需要让外界知道的信息隐藏起来
2、继承
子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为
3、多态
同一个行为具有多个不同表现形式或形态的能力
类定义
一般形式为:
class ClassName:
statement
类对象
类对象支持两种操作:属性引用(obj.name)和实例化:
class GoodClass: good = 1000 def GoodFunction(self): return 'this is a good function' c = GoodClass() # 实例化 print(c.good) # 访问属性和方法 print(c.GoodFunction())
结果为:
1000 this is a good function
类有一个名为__init__()的特殊方法,即构造方法,在类实例化时会自动调用, __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上:
class GoodClass: def __init__(self, n, a): self.name = n self.age = a s = GoodClass('大湘菜', 18) print(s.name)
结果为:
大湘菜
如果在类实例化时不传入参数会报错:
class GoodClass: def __init__(self, n, a): self.name = n self.age = a s = GoodClass() print(s.name)
结果为:
s = GoodClass()
TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,按照惯例它的名称是self。self代表类的实例,而非类:
class GoodClass: def print_self(self): print(self) print(self.__class__) s = GoodClass() s.print_self() # 注意不要写成print(s.print_self())
结果为:
<__main__.GoodClass object at 0x000002026CD9E220> <class '__main__.GoodClass'>
这说明self代表的是类的实例,代表当前对象的地址,而self.__class__指向类
类的方法
使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例
继承
子类(派生类)会继承父类(基类)的属性和方法:
class Base: x = 'Hi, I am base' def __init__(self, n, a): self.name = n self.age = a def info(self): print('姓名为{},年龄为{}'.format(self.name, self.age)) class Child(Base): def __init__(self, n, a): # 调用父类的构函 Base.__init__(self, n, a) c = Child('大湘菜', 18) c.info() print(c.x)
结果为:
姓名为大湘菜,年龄为18 Hi, I am base
子类和父类必须定义在同一个作用域内
多继承
一般形式为:
class Child(Base1, Base2, …)
statement
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左到右查找父类中是否包含方法
方法重写,即在子类重写父类的方法:
class Parent: def myMethod(self): print('I am parent') class Child(Parent): def myMethod(self): print('I am child') c = Child() c.myMethod() # 子类调用重写方法 super(Child, c).myMethod() # 用子类对象调用父类已被覆盖的方法
结果为:
I am child I am parent
其中super()函数用于调用父类(超类)
类的私有属性
以两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问
类的私有方法:
以两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用
类的专有方法
__init__ 构造函数,在生成对象时调用
__del__ 析构函数,释放对象时使用
__repr__ 打印,转换
__setitem__ 按照索引赋值
__getitem__ 按照索引获取值
__len__ 获得长度
__cmp__ 比较运算
__call__ 函数调用
__add__ 加运算
__sub__ 减运算
__mul__ 乘运算
__truediv__ 除运算
__mod__ 求余运算
__pow__ 乘方
运算符重载
可以对类的专有方法进行重载,即重新进行定义