面向对象编程
OOP(Object-Oriented Programming)编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述.
使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。
面向对象的几个核心特性如下
Class 类
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法
Object 对象
一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同
Encapsulation 封装
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
Inheritance 继承
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
Polymorphism 多态
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。
对不同类的对象发出相同的消息将会有不同的行为。比如,你的老板让所有员工在九点钟开始工作, 他只要在九点钟的时候说:“开始工作”即可,而不需要对销售人员说:“开始销售工作”,对技术人员说:“开始技术工作”, 因为“员工”是一个抽象的事物, 只要是员工就可以开始工作,他知道这一点就行了。至于每个员工,当然会各司其职,做各自的工作。
多态允许将子类的对象当作父类的对象使用,某父类型的引用指向其子类型的对象,调用的方法是该子类型的方法。这里引用和调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定
类的语法
class Dog(object):
print('Dog: Woof..Woof')
d = Dog()
使用class+类名(首字母大写)来定义一个类
d=Dog()就是将类实例化为对象
实例化,就是以Dog类为模板,在内存中开辟出一个空间,存上数据,赋值成一个变量名,核心是通过类对象指针去调用类中的数据
封装:
封装是面向对象的特征之一,是对象和类概念的主要特性。
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏
class Dog(object):
def __init__(self,name,dog_type):
self.name = name
self.dog_type = dog_type
def say_hi(self):
print('Dog %s: Woof..Woof' % self.name)
d = Dog('dog1','中华田园犬')
d.say_hi()
上面__init__和self分别是指什么呢?
我们看一张图:
__init__方法,是一个构造方法,用来初始化类的成员变量(成员属性)
当程序执行时,首先会在内存中开辟出内存空间,用来存放类中的成员变量(name,dog_type)和方法 say_hi
当进行实例化 d = Dog(‘dog1','中华田园犬')时
python会自动将d当成self传递给Dog,上面的语句等同于 Dog(d,'dog1',’中华田园犬‘)
然后,会将类中的成员变量复制到d的内存空间中,成为d.name和d.dog_type
同样,我们在调用类方法时,得告诉类,是谁在调用
d.say_hi() #python会自动转成 say_hi(d)
封装:就是使用构造方法将内容封装到某个具体对象中,然后通过对象直接或self间接获取被封装的内容
继承:
面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
通过继承创建的新类称为“子类”或“派生类”。
被继承的类称为“基类”、“父类”或“超类”。
继承的过程,就是从一般到特殊的过程。
class Person(object):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
self.other = 'others'
def talk(self):
print('person is talking....')
class BlackPerson(Person):
def __init__(self,name,age,sex,power):
#Person.__init__(self,name,age,sex)
super(BlackPerson,self).__init__(name,age,sex)
self.power = power
print(self.name,self.age,self.sex,self.power,self.other)
def talk(self):
Person.talk(self)
print('Black Person is talking...')
def walk(self):
print('Black Person is walking....')
p1 = Person('s1',16,'male')
p1.talk()
p2 = BlackPerson('s2',24,'male',100)
p2.talk()
p2.walk()
在上面的代码中,我们使用了super方法来继承了父类的信息,这种方式称为新式类,相对的,还有一种叫做经典类的继承:
class BlackPerson(Person):
def __init__(self,name,age,sex,power):
Person.__init__(self,name,age,sex)
#super(BlackPerson,self).__init__(name,age,sex)
self.power = power
print(self.name,self.age,self.sex,self.power,self.other)
在python3中,经典类和新式类的继承没有区别,但是,在python2.7中,这2种继承方式存在差异:
新式类:
class A(object):
#pass
def __init__(self):
self.n = "A"
class B(A):
pass
# def __init__(self):
# self.n = "B"
class C(A):
#pass
def __init__(self):
self.n = "C"
class D(B,C):
pass
# def __init__(self):
# self.n = "D"
d = D()
print(d.n)
执行结果为:
C
经典类:
class A:
#pass
def __init__(self):
self.n = "A"
class B(A):
pass
# def __init__(self):
# self.n = "B"
class C(A):
#pass
def __init__(self):
self.n = "C"
class D(B,C):
pass
# def __init__(self):
# self.n = "D"
d = D()
print(d.n)
执行结果:
A
在python2.7中,经典类的继承,是按照深度优先进行继承的;而新式类,则是按照广度优先进行继承
python3中,统一为广度优先进行继承
对于继承,不管对于成员变量还是方法,均会优先在子类中进行搜索,当在子类中没有找到对应的信息时,会去父类进行查找:
class F1(object):
def __init__(self):
print('F1')
def a1(self):
print('F1a1')
def a2(self):
print('F1a2')
class F2(F1):
def __init__(self):
print('F2')
def a1(self):
self.a2()
print('F2a1')
def a2(self):
print('F2a2')
class F3(F2):
def __init__(self):
print('F3')
def a2(self):
print('F2a2')
obj = F3()
obj.a1()
执行结果:
F2a2
F2a1
多态:
多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
多态的作用是为了接口的重用;为了类在继承和派生时,保证使用“家谱”中任一类的实例的某一属性时的正确调用
Pyhon不直接支持多态,但可以间接实现
class Animal(object):
def __init__(self,name):
self.name = name
def talk(self):
raise NotImplementedError("Subclass must implement abstract method")
class Dog(Animal):
def talk(self):
print("Woo,Woo")
class Cat(Animal):
def talk(self):
print("Meow")
#目标是实现真正的多态,通过父类直接调用子类的方法
#Animal.talk(c)
#Animal.talk(d)
d = Dog('dog1')
c = Cat('cat1')
d.talk()
c.talk()
def anmial_talk(obj):
obj.talk()
anmial_talk(c)
anmial_talk(d)