继承
单继承
简单来说,一个子类只能有一个父类,被称为单继承
注意:在使用继承时,尽量一个类存在于一个模块中
比如,我们定义了一个Animal的class,有一个run()方法
class Animal(object):
def run(self):
print("Animal is running....")
当我们需要编写Dog和Cat类时,就可以直接从Animal类继承:
class Dog(Animal):
pass
class Cat(Animal):
pass
对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类,Cat和Dog类似。
继承有什么好处?最大的好处就是子类获得了父类的全部功能,由于Animal实现了run()方法,因此,Dog和Cat作为它的子类,什么事也没干,就自动拥有了run()的方法。
dog = Dog()
dog.run()
cat = Cat()
cat.run()
当然,也可以对子类增加一些方法,比如Dog类:
class Dog(Animal):
def eat(self):
print("Eating meat....")
#以前的写法 class Person(object):
#但是实质上,如果没有显示的写出父类,则这个类的父类默认为object
#object是所有类的父类或者超类
class Person(object):
#构造方法
def __init__(self, name, age, money):
self.name = name
self.age = age
self.__money = money
#get/set方法
def setMoney(self, money):
self.__money = money
def getMoney(self):
return self.__money
def run(self):
print("run")
def eat(self, food):
print("eat", food)
from person import Person
class Student(Person):
def __init__(self, name, age, money, stuId):
#调用父类中的构造方法
#方法1 super(当前类,self).__init__(参数列表)
#super(Student,self).__init__(name, age, money, stuId)
#方法2 父类名.__init__(属性列表)
Person.__init__(self, name, age, money)
#子类可以有一些自己独有的属性
self.stuId = stuId
def setFunc(self):
print(self.__money)
from person import Person
class Worker(Person):
def __init__(self, name, age, money)
super(Worker,self).__init__(name, age, money)
# 在子类中定义和一个父类中重名的函数
def run(self):
print("子类中的run方法被调用了")
总结:
继承的特点:
a. 子类对象可以直接访问父类中未私有的对象
b. 子类对象可以调用父类中的方法
c. 父类对象不能访问子类中特有的属性或者方法
优缺点:
优点:
1.可以简化代码,减少冗余
2.提高代码的维护性
3.提高了代码的安全性
缺点:
耦合和内聚被用来描述类与类之间的关系,耦合性越低,内聚性越高,说明代码越好,
但是,在继承关系中,耦合性相对比较高,如果修改父类,子类也会随着变化
多继承
顾名思义:就是一个子类中可以有多个父类,比如一个孩子有一个爸爸一个妈妈
from child import Child
def main():
c = Child(300, 100)
print(c.money, c.faceValue)
c.play()
c.eat()
#注意:如果多个父类中的方法名相同,默认调用的是子类括号中排前面的父类中的方法
#此时调用的是Father中func方法
if __name__ == "__mian__":
main()
class Father(object):
def __init__(self, money):
self.money = money
def play(self):
print("play")
def func(self):
print("Father")
class Mother(object):
def __init__(self, faceValue):
self.faceValue = faceValue
def eat(self):
print("eat")
def func(self):
print("Mother")
from father import Father
from mother import Mother
class Child(Father, Mother):
def __init__(self, money, faceValue):
#注意:分别调用各个父类中的构造方法
Father.__init__(self, money)
Mother.__init__(self, faceValue)
#子类中同样可以有自己独有的特性
总结:
- 子类可以从多个父类中继承属性和方法
- 一个父类可以有多个子类
- 一个子类可以有多个父类
多态
多态是指一类事物的有多种状态【一个抽象类有很多子类,因而多态的概念依赖于继承。】
1.序列有多种形态:字符串,列表,元组
2.动物有多中形态:猫,狗
定义父类:
class Animal(object):
def run(self):
print("Animal is running....")
定义子类:
class Dog(Animal):
def run(self):
print("Dog is running...")
def eat(self):
print("Eating meat....")
继承的第二个好处是,我们可以在自己需要的时候,对我们的代码进行改进。当子类与父类都存在相同的run()方法的时候,子类中的run()覆盖了父类中的run(),在代码运行的时候,总会调用子类中的run().
这时候我们就获取了继承的另外一个好处:多态。
若要理解多态,我们首先要对数据类型再进行说明,我们定义一个class的时候,其实就是定义了一种数据类型。
a = list() #a是list类型
b = Animal() #b是Animal类型
c = Dog() #c是Dog类型
判断一个变量是否是某个类型们可以使用instance()来判断
>>>isinstance(a,list)
True
>>>isinstance(b,Animal)
True
>>>isinstance(c,Dog)
True
#c不仅是Dog还是Animal
>>>isinstance(c,Animal)
True
在继承的关系中,如果一个实例的数据类型是某个子类,那么它的数据类型也可以被看做是父类。
多态的优点:
class Animal(object):
#def run(self):
# print("Animal is running....")
@staticmethod
def run2(Animal):
Animal.run()
class Dog(Animal):
def run(self):
print('Dog is running...')
class Cat(Animal):
def run(self):
print('Cat is running...')
Animal.run2(Dog())
Animal.run2(Cat())
#结果
Dog is running...
Cat is running...
新增子类的时候我们不需要对我们的run2()做任何的修改,任何依赖Animal作为参数的函数都可以不加修饰的正常的运行。
多态的优点就是,当我们需要传入Dog,Cat,…时我们只需要接收Animal类型的即可,因此,传入的类型只要是Animal类或者是子类,就会自动调用实际类型的run()方法,这就是多态的意思。
获取对象属性
使用type()来判断对象类型
>>>type(123)
若是一个变量指向函数或者是类,依然可以使用type()判断。
isinstance()可以判断一个对象是否属于某种类型
>>> a = Animal()
>>> b = Dog
>>> isinstance(a,Animal)
True
>>> isinstance(b,Animal)
True
还可以判断一个变量是否是某些类型中的一种,比如下面的代码:
>>> isinstance([1,2,3],(list,tuple))
True
使用dir()函数可以获取一个对象的所有的属性和方法,它返回一个包含字符串的list
>>> dir(a)
函数重写
'''
重写:将函数重写一遍
__str__():在调用print打印对象时自动调用,是给用户用的,是一个描述对象的方法.
__repr__():是给机器用的,在python解释器里面直接敲对象名在回车后调用方法
注意:在没有str时,且有repr,__str__=__repr__
'''
class Animal(object):
def __init__(self, name, age, height, weight):
self.name = name
self.age = age
self.height = height
self.weight = weight
def __str__(self):
return "%s-%d-%d-%d"%(self.name, self.age, self.height, self.weight)
ani = Animal("大黄", 5, 60, 25)
#print(per.name, per.age, per.height, per.weight)
#在打印ani时自动调用str函数
print(ani)
#优点或者使用时机:当一个对象的属性值很多,并且都需要打印,重写__str__方法后,简化了代码,方便查看.