1.面向过程编程:计算机通过一系列指令来一步一步完成任务。
2.面向对象编程(oop):通过“类”和“对象”来创建模型,用于对真实世界进行描述。
3.Class 类
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象都具备的属性(variables(data))和相同的方法 。
4.Object 对象
一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同
5.Encapsulation 封装
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
6.Inheritance 继承
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
7.Polymorphism 多态
态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。
对不同类的对象发出相同的消息将会有不同的行为。比如,你的老板让所有员工在九点钟开始工作, 他只要在九点钟的时候说:“开始工作”即可,而不需要对销售人员说:“开始销售工作”,对技术人员说:“开始技术工作”, 因为“员工”是一个抽象的事物, 只要是员工就可以开始工作,他知道这一点就行了。至于每个员工,当然会各司其职,做各自的工作。
多态允许将子类的对象当作父类的对象使用,某父类型的引用指向其子类型的对象,调用的方法是该子类型的方法。这里引用和调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定
8.无论用什么形式来编程,我们都要明确记住以下原则:
- 写重复代码是非常不好的低级行为
- 你写的代码需要经常变更
9.类的定义
新式类:class Role(object): 推荐用新式类
经典类:class Role:
新式类与继承类的区别就是子类在继承父类的时候,括号内父类顺序可以随便写:class Son3(Father,jiao_you):
类中有四个重要点:私有属性、私有函数、继承、多态
class Role:
n = 123 #名称【类变量】,用不到可不写,存在类的内存里,而不是实例的内存里【注意:如果实例里也有n,则实例在调用n的时候就会调用实例里的n,就进化原则】
如果n不是列表,则在某一实例中修改n的值,只会修改该实例中n的值,而类的n和其他实例的n都不会变
如果n是列表,则在某一实例中修改n的值,则会修改该实例中n的值,而类的n和其他实例的n都会被修改,因为他们使用的都是同一个列表
def __init__(self,name,role) #实例化的时候(r1 = Role()),用到self,这里的self指代实例名r1,若r2= Role(),则self指代r2.
#__init__函数的作用:它就是构造函数,即初始化函数(与之对应的是析构函数),就是在将类实例化的时候(r1 = Role()),在内存里开辟一块内存,内存里存放了定义的变量,方便r1使用
self.name = name #(name为实例变量【又称静态属性】,实例变量只能作用于实例本身)#r1 = Role() ======>> r1 = Role(r1,name,role) 【俩r1不一样,python直接将实例名作为对象名】=======>> 为了这个类
self.role = role #能给其他实例用,所以用self指代第二个r1
self.__age = age #私有属性,(__表示私有)实例的私有属性不能被外部函数或其他实例修改,就算实例自己直接调用也不行(如:print(r1.__age) 会报错),只能再在类里定义一个函数,让该函数查看或修改私有属性,self.__age。
def __del__(self): #__del__函数就是析构函数,它会在最后一个该类的实例运行结束后自动执行,用来关闭打开的临时文件等,回收内存。但是在执行del r1(删除r1实例)语句后,析构函数也会执行。
print("%s I am gone!" %self.name)
def hehe(self,name): #定义的函数【又称动态属性】,在定义函数的时候,每个函数都必须加上self
print("%s 呵呵" % self.name)
def __hello(self): #私有函数,(__表示私有)实例的私有函数不能被外部函数或其他实例调用,就算是实例自己直接调用也不行(如:r1.__hello() 会报错),只能再在类里定义一个函数,让该函数调用私有函数,调用的时候要用这样 self.__hello() 。
print("hello! %s" % self.name)
r1 = Role(‘wt‘,‘student‘) #实例初始化,括号里的是默认值
r1.属性 (如下,调用类中的函数或类变量)
r1.add_other = ‘I am other‘ #给实例添加额外属性【实例属性的增删改查只作用于本实例,不作用于另一个实例,更不作用于类】
r1.name = ‘eric‘ #修改实例默认值
del r1.name #删除实例的name属性,并不会删除类的name属性
r1.hehe(‘wt‘) #调用hehe函数
输出:wt 呵呵
10.继承
class Father(object): #定义一个父类
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print("%s is eating" % self.name)
def sleep(self):
print("%s is sleeping" % self.name)
class Jiao_you(object): #这个父类是用来让子类多继承用的,不需要__init__函数
def make_friends(self,obj): #obj参数是指代对象变量,而不是普通变量
print("%s make friends with %s" %(self.name,obj.name)) #这里的name变量是子类的name变量,只有在对子类实例化后才生效
class Son(Father): #定义一个子类,单继承
def new(self): #定义一个新函数new(),相对父类来说,又称函数重构
Father.eat(self) #可以这样调用父类的函数
class Son2(Father): #定义另一个子类,想让这个子类增加新功能
def __init__(self,,name,age,money): #money为新增加的功能
Father.__init__(self,name,age) #先调用父类的__init__()函数
等同于super(Son2,self).init(name,age) #推荐用super(),也是先调用父类的__init__()函数,但是它会自己分配继承顺序
self.money = money #再初始化新增加的变量
def hello(self): #定义一个新函数hello()
Father.eat(self) #可以这样调用父类的函数
print("花费:%s" % self.money)
class Son3(Father,jiao_you): #定义第三个子类,这是多继承
def new(self): #定义一个新函数new(),相对父类来说,又称函数重构
Father.eat(self) #可以这样调用父类的函数
son1 = Son("Alex",50) #将Son类实例化为son1
son1.sleep() #输出:Alex is sleeping
son1.new() #输出:Alex is eating
son_Alex = Son3(‘Alex‘,50) #将Son3类实例化为son_Alex
son_Eric = Son3(‘Eric‘,20) #将Son3类实例化为son_Eric
son_Alex.make_friends(son_Eric) #输出:Alex make friends with Eric 这里的son_Eric实例就是父类函数make_friends(self,obj)的参数obj
11.继承顺序
(1)广度优先 在python3中是按广度优先继承的
class B(A): B继承A
class C(A): C继承A
class Son3(B,C): #子类Son3先继承B,找不到B再找C,最后再找A
(2)深度优先 在python2中经典类是按深度优先继承的,新式类是按广度优先继承的
class B(A): B继承A
class C(A): C继承A
class Son3(B,C): #子类Son3先继承B,找不到B再找A
12.多态
多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。
Pyhon不直接支持多态,但可以间接实现
通过Python模拟的多态
1 class Animal: 2 def __init__(self, name): # Constructor of the class 3 self.name = name 4 def talk(self): # Abstract method, defined by convention only 5 raise NotImplementedError("Subclass must implement abstract method") 6 7 class Cat(Animal): 8 def talk(self): 9 return ‘Meow!‘ 10 11 class Dog(Animal): 12 def talk(self): 13 return ‘Woof! Woof!‘ 14 15 animals = [Cat(‘Missy‘), 16 Dog(‘Lassie‘)] 17 18 for animal in animals: 19 print animal.name + ‘: ‘ + animal.talk()