面向对象OO(Object Oriented)相关的词汇有OOP(面向对象编程),OOD(面向对向设计),OOA(面向对象分析)OOS(面向对象服务等)等,那么什么是面向对象呢?
面向对象
面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物,详细参考百科。拆分开口语化来理解,面向:从什么的方向出发,对象:一个抽象化的目标(具有一定的属性或特性以及具有一定的方法或动作)。合起来就是:从一个抽象化目标的方向出发,去做什么,具有从整体到局部的导向性。如:OOP从一个抽象化目标的方向出发,去编程。
面向对象的特性
了解面向对象之前先要了解类,先看下与类有关的词语:类比,同类,类型,物以类聚等等都提到了“类”,由此可见与“类”相关说明有很多共性存在。类是具有相同特性(数据元素)和行为(功能)的万物的抽象。即万物抽象化后为类,类实例化后为对象。至于抽象后叫什么类自定义,鸟类,人类,猫科类等等。面向对象具有封装,继承,多态的特性。

封装:对数据和行为的包装和信息隐藏。
继承:有利于衍生的一种层次模型,继承者为子类(又叫派生类),被继承者为父类(又叫基类),子类具有父类的可继承属性和方法。Python没有java中的接口实现方式,可多继承。继承的父类在类的定义后的括号中逗号隔开,object一般不描述,默认继承。
class C(object,A,B):#C继承自A和B,A、B必须是存在的类
pass
多态:指不同事物具有不同表现形式的能力。多态机制使具有不同内部结构的对象可以共享相同的外部接口,通过这种方式减少代码的复杂度。一个接口,多种方式。主要体现在面向接口编程的语言中,如java的父类引用指向子类对象。Python中多态不太好体现。因为其类型为隐藏类型,不比其他的声明式类型的语言。
方法和变量
方法是类中定义的函数,变量分为类变量和方法变量,类变量是函数体之外,类之中的变量,在整个类中可以使用,方法变量是方法内部定义的变量,只能在方法中使用。类变量也可以理解为属性。属性也可在类的构造方法__init__()中通过self.XXX 来设置。
类的默认方法
Python中所有类都继承超级基类 object,所以类拥有如下超级基类的方法如下:
- __init__() : 构造函数,来自“initialize”简写。可自定义参数,在生成对象时调用。
- __del__() : 析构函数,来自“delete”简写。释放对象时使用。
- __repr__() : 打印,转换。来自“reprint”简写。
- __setitem__(): 按照索引赋值。
- __getitem__(): 按照索引获取值
- __len__(): 获得长度,来自“length”简写
- __cmp__(): 比较运算,来自“compare”简写
- __call__(): 函数调用
- __add__(): 加运算
- __sub__(): 减运算
- __mul__(): 乘运算
- __truediv__(): 除运算
- __mod__(): 求余运算
- __pow__(): 乘方
更多非类默认函数的具体使用参考另一篇:基础篇之函数
类的实现
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。此处以经典的动物作为案例实现。
- 创建动物基类Animal
class Animal(object):#类名Animal
'''
动物类定义
'''
#但类变量一般是常量等共用的数据
CLASSNAME=None#类变量:脚的数量,也是属性
def __init__(self):
print("Animal 正在实例化...")
self.name=None#属性:名称
self.color=None#属性:颜色
'''
# 带参数的构造函数,构造函数只能有一个
def __init__(self,name,color):
self.name = name
self.color = color
'''
#自定义方法
def moving(self):
print(self.color+"的"+self.name+"正在移动")
#自定义方法
def eating(self):
print(self.color+"的"+self.name+"正在吃东西")
#自定义方法
def showInfo(self):
print("\nname="+self.name+",color="+str(self.color))
- 创建两个子类继承自基类Animal
class Dog(Animal):
def __init__(self,name,color):
Animal.__init__(self)#重写构造函数,如果构造函数带参数,此处可略
self.CLASSNAME = "Dog"
self.name = name
self.color = color
class Pig(Animal):
def __init__(self,name,color):
Animal.__init__(self)#重写构造函数,如果构造函数带参数,此处可略
self.CLASSNAME = "Pig"
self.name = name
self.color = color
- 测试调用
if __name__ == "__main__":
dog1 = Dog("哈士奇","白色")
dog2 = Dog("哈士奇","黑色")
dog3 = Dog("泰迪","白色")
pig1 = Pig("种猪","黑色")
dog1.showInfo()
dog1.moving()
dog1.eating()
dog2.showInfo()
dog2.moving()
dog2.eating()
dog3.showInfo()
dog3.moving()
dog3.eating()
pig1.showInfo()
pig1.moving()
pig1.eating()
-
输出结果
执行结果.png
- 属性的操作
上面案例中用到了方法重写,类的声明,类的继承,变量的使用,实例对象的创建及方法的调用等。关于属性的使用,关于Python中get/set方法可以自己在类中定义,如在基类中定义如下方法:
def setName(self,name):
self.name = name
def getName(self):
return self.name
与自定义get/set方法,Python有内置的函数处理,用内置函数的前提是知道具体的属性,否则会报:AttributeError。如下是等价的:
print("getName获取值:"+dog1.getName())#获取属性
print("getattribute获取值:"+dog1.__getattribute__('name'))
dog1.setName("哈士奇二代")#设置属性
print("getName获取值:"+dog1.getName())#获取属性
print("getattribute获取值:"+dog1.__getattribute__('name'))
dog1.__setattr__('name',"哈士奇三代")
print("getName获取值:"+dog1.getName())#获取属性
print("getattribute获取值:"+dog1.__getattribute__('name'))
如上代码dog1对象的名字从哈士奇 改为了 哈士奇二代。输出如下:

类的其他知识
- super() 函数是用于调用父类(基类)的一个方法。
- 方法重写,是重写父类中已存在的方法,在本对象或者实例中有效
- 私有属性和方法,在属性名或方法明前+“__”(两个下划线)
如: 类的私有属性,通过__private_attrs 定义属性名,外部不能调用
如: 类的私有方法,通过__private_method定义方法名,外部不能调用 - 如果重写了__init__ 时,实例化子类,就不会调用父类已经定义的 __init__,要调用可以通过:父类名称.__init__(self,参数1,参数2,...)
- 自定义类自定义私有方法是,不要跟超类object中已存在的方法名(超级基类默认方法)重复。
网友评论