封装
封装的两方面含义:
将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂程度。
在类对象的内部通过访问控制把某些属性和方法隐藏起来,不允许类对象的外部直接访问,而是在类对象的内部对外提供公开的接口方法(例如getter和setter)以访问隐藏的信息。这样,就对隐藏的信息进行了保护。
class (object):
def __init__(self):
self.__score = 0 # 把内部属性隐藏起来,不允许直接访问
def get_score(self):
print(self.__score)
def set_score(self, score): # 在方法内部对属性进行操作。
if 100 >= score >= 0:
self.__score = score
else:
raise ValueError('输出数值错误!')
xiaoming = Student()
xiaoming.set_score(60) # 在类对象的外部调用方法。
xiaoming.get_score()
xiaoming.set_score(85)
xiaoming.get_score()
继承
继承是实现代码复用的重要手段。
# 继承
class Animal(object):
def __init__(self, name):
self.name = name
def drink(self):
print('%s drink water' % self.name)
def eat(self):
print('%s eat some thing' % self.name)
class Dog(Animal): # 继承Animal的属性和方法
def swim(self):
print('%s swim' % self.name)
class Bird(Animal):# 继承Animal的属性和方法
def fly(self):
print('%s fly' % self.name)
dog = Dog('dog')
bird = Bird('bird')
dog.drink()
bird.drink()
dog.swim()
bird.fly()
Python中的所有类对象都继承自一个统一的基类:object。
子类只有一个直接父类时,称为==单继承==。子类有多个直接父类时,称为==多继承==。
子类会继承所有父类(包括直接父类和所有间接父类)的所有属性和方法。
重写
在子类中定义与父类同名的属性或方法,就可以重写该属性或方法。
子类重写父类方法后,通过子类或其实例对象只能调用子类中重写后的方法,而无法调用父类中被重写分方法。
子类可以通过super().xxx()调用父类中的方法。
==Python3.x 和 Python2.x 的一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx :==
Python3.x 实例:
class A:
pass
class B(A):
def add(self, x):
super().add(x)
Python2.x 实例:
class A(object): # Python2.x 记得继承 object
pass
class B(A):
def add(self, x):
super(B, self).add(x)
多态
简单的说,多态就是“具有多种形态”。
多态可以理解为同样一件事情,不同的人做,会有不同的效果。
一个方法,传递不同的实例对象,执行对应实例的不同方法,产生不同的效果。
# 多态
class Animal(object):
def __init__(self):
self.name = 'Animal'
def eat(self):
print(self.name + ' eat')
class Dog(Animal):
def __init__(self):
self.name = 'Dog'
def bark(self):
print(self.name + ' bark')
class Bird(Animal):
def __init__(self):
self.name = 'Bird'
def fly(self):
print(self.name + ' fly')
def animal_eat(animal): # 实现多态的函数
animal.eat()
animal = Animal()
dog = Dog()
bird = Bird()
animal_eat(animal)
animal_eat(dog)
animal_eat(bird)
python是动态语言,在调用函数时不会检查参数的类型,从而导致与静态语言(如Java)的多态是有区别的。对于静态语言,实现多态有三个必要的条件:
继承
重写
父类类型的变量引用父类或子类类型的实例对象