面向对象编程有三大重要特征
封装、继承和多态。
封装
封装是指将数据与具体操作的实现代码放在某个对象内部,使这些代码的实现细节不被外界发现,外界只能通过接口使用该对象,而不能通过任何形式修改对象内部实现,正是由于封装机制,程序在使用某一对象时不需要关心该对象的数据结构细节及实现操作的方法。使用封装能隐藏对象实现细节,使代码更易维护,同时因为不能直接调用、修改对象内部的私有信息,在一定程度上保证了系统安全性。类通过将函数和变量封装在内部,实现了比函数更高一级的封装。
class Student:
room = '101'
address = 'changsha'
def __init__(self, name, age):
self.name = name
self.age = age
def print_age(self):
print('%s: %s' % (self.name, self.age))
# 以下是错误的用法
# 类将它内部的变量和方法封装起来,阻止外部的直接访问
print(room)
print(adress)
print_age()
继承
继承来源于现实世界,一个最简单的例子就是孩子会具有父母的一些特征,即每个孩子都会继承父亲或者母亲的某些特征,当然这只是最基本的继承关系,现实世界中还存在着更复杂的继承。继承机制实现了代码的复用,多个类公用的代码部分可以只在一个类中提供,而其他类只需要继承这个类即可。
继承最大的好处是子类获得了父类的全部变量和方法的同时,又可以根据需要进行修改、拓展。其语法结构如下:
class Foo(superA, superB,superC....):
class DerivedClassName(modname.BaseClassName): ## 当父类定义在另外的模块时
Python支持多父类的继承机制,所以需要注意圆括号中基类的顺序,若是基类中有相同的方法名,并且在子类使用时未指定,Python会从左至右搜索基类中是否包含该方法。一旦查找到则直接调用,后面不再继续查找。
# 父类定义
class people:
def __init__(self, name, age, weight):
self.name = name
self.age = age
self.__weight = weight
def speak(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))
# 单继承示例
class student(people):
def __init__(self, name, age, weight, grade):
# 调用父类的实例化方法
people.__init__(self, name, age, weight)
self.grade = grade
# 重写父类的speak方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))
s = student('ken', 10, 30, 3)
s.speak()
Python3的继承机制
Python3的继承机制不同于Python2。其核心原则是下面两条,请谨记!
子类在调用某个方法或变量的时候,首先在自己内部查找,如果没有找到,则开始根据继承机制在父类里查找。
根据父类定义中的顺序,以深度优先的方式逐一查找父类!
super()函数
我们都知道,在子类中如果有与父类同名的成员,那就会覆盖掉父类里的成员。那如果你想强制调用父类的成员呢?使用super()函数!这是一个非常重要的函数,最常见的就是通过super调用父类的实例化方法__init__!
语法:super(子类名, self).方法名(),需要传入的是子类名和self,调用的是父类里的方法,按父类的方法需要传入参数。
class A:
def __init__(self, name):
self.name = name
print("父类的__init__方法被执行了!")
def show(self):
print("父类的show方法被执行了!")
class B(A):
def __init__(self, name, age):
super(B, self).__init__(name=name)
self.age = age
def show(self):
super(B, self).show()
obj = B("jack", 18)
obj.show()
多态
先看下面的代码:
class Animal:
def kind(self):
print("i am animal")
class Dog(Animal):
def kind(self):
print("i am a dog")
class Cat(Animal):
def kind(self):
print("i am a cat")
class Pig(Animal):
def kind(self):
print("i am a pig")
# 这个函数接收一个animal参数,并调用它的kind方法
def show_kind(animal):
animal.kind()
d = Dog()
c = Cat()
p = Pig()
show_kind(d)
show_kind(c)
show_kind(p)
------------------
打印结果:
i am a dog
i am a cat
i am a pig
狗、猫、猪都继承了动物类,并各自重写了kind方法。show_kind()函数接收一个animal参数,并调用它的kind方法。可以看出,无论我们给animal传递的是狗、猫还是猪,都能正确的调用相应的方法,打印对应的信息。这就是多态。
实际上,由于Python的动态语言特性,传递给函数show_kind()的参数animal可以是 任何的类型,只要它有一个kind()的方法即可。动态语言调用实例方法时不检查类型,只要方法存在,参数正确,就可以调用。这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
原文:https://www.cnblogs.com/sakura579/p/12431161.html