24-1 面向对象(创建类和对象、面向对象三大特性)
编程其实就是一个将具体世界进行抽象化的过程,面向对象编程(Object Oriented Programming,OOP)是利用“类”和“对象”来创建各种模型来实现对真实世界的描述。
- 类(class): 一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的具备的共同的属性、共同的方法。
- 对象(object): 一个对象即是一个类的实例化来的,一个类可以实例化出多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之间有共性,亦有不同。
python既支持函数式编程也支持面向对象编程(而比如Java和C#来说只支持面向对象编程),一般在Python开发中,全部使用面向对象或面向对象和函数式混合使用。
创建类和对象
创建对象的过程,就是将类实例化的过程。
1. 创建类和对象
# 创建类 class Student(object): # object写不写都行,因为系统内部都会给写上。所有类都继承object school = "oldboy" # 静态字段 term = "fulltack2" def __init__(self, name, age): # 创建对象时,自动执行的特殊方法。 self.name = name self.age = age def show(self): # 类中定义的函数叫方法。 print(self.name, self.age ) def func(self): return self.age + 2 # 创建对象 obj1 = Student("alex", 18) # 创建对象,类名称后加括号 obj2 = Student("jack", 20) # 调用 obj1.show() # 调用方式一:通过类对象指针找到方法,self参数自动传入。建议这样用 Student.show(obj1) # 调用方式二:通过类找到其中的方法,参数需要自己传入 ret = obj1.func() # 接收方法的返回值 print(ret) # 输出:20
2. 实例化的内部过程
“实例化”, 就是把一个虚拟的抽象的类,通过这个动作,变成了一个具体的对象了, 这个对象就叫做实例。

(1)__init__()
类中的__init__方法叫初始化方法(或构造方法)。在生成一个角色时要初始化的一些属性就填写在这里。
当解释器解释到obj = 类名() 这句话时,会做两件事情:①创建对象 ②通过对象执行类中的构造方法__init__()
(2)self
self 是一个形参,它代指对象本身。如:执行 obj1 = Student('alex', 18 ) 时,self 等于 obj1; 当执行 obj2 = Student('jack', 20) 时,self 等于 obj2。
第一个参数名称必须为self是类的方法(普通方法)与普通的函数的一个区别,但是在调用这个方法的时候不用给这个参数赋值,因为Python会提供这个值。
按照惯例它的名称是self,虽然你可以给这个参数任何名称,但是 强烈建议 你使用self这个名称。
为什么要有self参数?
假设有一个类称为MyClass和这个类的一个实例MyObject。
当调用这个对象的方法MyObject.method(arg1, arg2)时,Python处理时实际会转为MyClass.method(MyObject, arg1, arg2),self 即代指MyObject。
调用类中的一个方法时,你得告诉人家你是谁,否则如何操作对象中的属性?!

面向对象三大特性
面向对象的三大特性是指:封装、继承和多态。
一、 封装(Encapsulation)
其实就是使用构造方法将内容装到某个具体对象中,然后通过对象直接或者self间接获取被封装的内容:
- 通过对象直接调用 对象名.属性名
- 通过self间接调用 self.属性名
二、继承
1. 继承
继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
通过继承创建的新类称为“子类”或“派生类”。
被继承的类称为“基类”、“父类”或“超类”。
OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段
class 父类:
pass
class 子类(父类):
pass
class Animal: def eat(self): print("%s 吃 " % self.name) def drink(self): print("%s 喝 " % self.name) def shit(self): print("%s 拉 " % self.name) def pee(self): print("%s 撒 " % self.name) class Cat(Animal): def __init__(self, name): self.name = name self.breed = '猫' def cry(self): print('喵喵叫') class Dog(Animal): def __init__(self, name): self.name = name self.breed = '狗' def cry(self): print('汪汪叫') c1 = Cat('小明家的小黑猫') c1.eat() # 小明家的小黑猫 吃 d1 = Dog('胖子家的小瘦狗') d1.eat() # 胖子家的小瘦狗 吃
#!_*_coding:utf-8_*_ # __author__:"Alex Li" class SchoolMember(object): members = 0 # 初始学校人数为0 def __init__(self, name, age): self.name = name self.age = age def tell(self): pass def enroll(self): '''注册''' SchoolMember.members += 1 print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " % ( self.name, SchoolMember.members)) def __del__(self): '''析构方法''' print("\033[31;1mmember [%s] is dead!\033[0m" % self.name) class Teacher(SchoolMember): def __init__(self, name, age, course, salary): super(Teacher, self).__init__(name, age) self.course = course self.salary = salary self.enroll() def teaching(self): '''讲课方法''' print("Teacher [%s] is teaching [%s] for class [%s]" % (self.name, self.course, 's12')) def tell(self): '''自我介绍方法''' msg = '''Hi, my name is [%s], works for [%s] as a [%s] teacher !''' % (self.name, 'Oldboy', self.course) print(msg) class Student(SchoolMember): def __init__(self, name, age, grade, sid): super(Student, self).__init__(name, age) self.grade = grade self.sid = sid self.enroll() def tell(self): '''自我介绍方法''' msg = '''Hi, my name is [%s], I'm studying [%s] in [%s]!''' % (self.name, self.grade, 'Oldboy') print(msg) if __name__ == '__main__': t1 = Teacher("Alex", 22, 'Python', 20000) t2 = Teacher("TengLan", 29, 'Linux', 3000) s1 = Student("Qinghua", 24, "Python S12", 1483) s2 = Student("SanJiang", 26, "Python S12", 1484) t1.teaching() t2.teaching() t1.tell()
2. 重写
如果父类中的某个方法不想继承,就在子类中写一个同名的方法。解释器找到子类中该名称的方法后,就不再去找父类中的同名方法。查找顺序如下:

class F: def f1(self): print('F.f1') def f2(self): print('F.f2') class S(F): def s1(self): print('S.s1') def f2(self): # 同名,父类中f2不再继承 print('S.f2') obj = S() obj.f1() # F.f1 obj.f2() # S.f2
3. 子类中手动执行父类中的方法
super(子类, self).父类中的方法(...)
父类名.父类中的方法(self,...)
class F: def f1(self): print('F.f1') def f2(self): print('F.f2') class S(F): def s1(self): print('S.s1') def f2(self): print('S.f2') super(S, self).f2() # 找到父类,执行父类中f2 方式一,推荐用这种方法 F.f2(self) # 找到父类,执行父类中f2 方式二 obj = S() obj.f1() # F.f1 obj.f2() # S.f2 # F.f2 # F.f2
4. 多继承
a. 左侧优先
一个子类同时继承多个类时,先搜索左边的类。

class F1: def a(self): print('F1.a') class F2: def a(self): print('F2.a') def b(self): print('F2.b') class S(F1, F2): pass obj =S() obj.a() # F1.a obj.b() # F2.b
b. 一条道走到头,再回头

class F0: def a(self): print('F0.a') class F1(F0): def b(self): print('F1.b') class F2: def a(self): print('F2.a') def c(self): print('F2.c') class S(F1,F2): pass obj =S() obj.a() # F0.a obj.c() # F2.c
c. 同一个根时,根最后执行

# 以次改变函数名,一步步试 class Base: def a(self): print('Base.a') class F0(Base): def a(self): print('F0.a') class F1(F0): def a(self): print('F1.a') class F3(Base): def a(self): print('F3.a') class F2(F3): def a(self): print('F2.a') class S(F1,F2): pass obj =S() obj.a()
三、多态
多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
Python多态示例:
class Animal(object): def __init__(self, name): # Constructor of the class self.name = name def talk(self): # Abstract method, defined by convention only raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): def talk(self): print('%s: 喵喵喵!' % self.name) class Dog(Animal): def talk(self): print('%s: 汪!汪!汪!' % self.name) def func(obj): # 一个接口,多种形态 obj.talk() c1 = Cat('小晴') d1 = Dog('李磊') func(c1) func(d1)
参考:
http://www.cnblogs.com/wupeiqi/p/4493506.html
http://www.cnblogs.com/alex3714/articles/5188179.html
http://python.jobbole.com/81921/
浙公网安备 33010602011771号