Python面向对象(组合、菱形继承、多态)
今日内容:
1.组合
2.菱形继承
3.多态与多态性
昨天内容重点回顾:
1)调用也叫实例化:发生了2件事
1.创造空对象
2.触发对象下的__init__方法,然后将p连同参数一同传给init
2)绑定关系
1.类的调用就是普通函数
2.大多数给对象调用的,绑定给对象用的
绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入
精髓:对象不仅是一系列数据(自己独有的+与其他对象共有的),还包含专门操作该数据的方法
1.组合
1、什么是组合
组合就是一个类的对象具备某一个属性,该属性的值是指向另外外一个类的对象
2、为何用组合
组合也是用来解决类与类直接代码冗余问题的
3、如何用组合
实例:选课系统
class Course:
def __init__(self,name,period,price):
self.name=name
self.period=period
self.price=price
def tell_info(self):
msg="""
课程名:%s
课程周期:%s
课程价钱:%s
""" %(self.name,self.period,self.price)
print(msg)
#老师和学生的父类
class OldboyPeople:
school = 'oldboy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
#学生类
class OldboyStudent(OldboyPeople):
def __init__(self,name,age,sex,stu_id):
OldboyPeople.__init__(self,name,age,sex)
self.stu_id=stu_id
def choose_course(self):
print('%s is choosing course' %self.name)
#老师类
class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, sex, level):
OldboyPeople.__init__(self,name,age,sex)
self.level=level
def score(self,stu,num):
stu.score=num
print('老师[%s]为学生[%s]打分[%s]' %(self.name,stu.name,num))
# 创造课程
python=Course('python全栈开发','5mons',3000)
linux=Course('linux运维','5mons',800)
# python.tell_info()
# linux.tell_info()
# 创造学生与老师
stu1=OldboyStudent('猪哥',19,'male',1)
tea1=OldboyTeacher('egon',18,'male',10)
stu1.choose_course()
tea1.score(stu1,99)
# 》》》》实现的目的是直接通过stu1和teal调用课程
# 将学生、老师与课程对象关联/组合
stu1.course=python #》》》》通过中间变量的值指向课程类的对象
tea1.course=linux
stu1.course.tell_info()
tea1.course.tell_info()
"""
super去改写版本:
class OldboyStudent(OldboyPeople):
def __init__(self,name,age,sex,stu_id):
# OldboyPeople.__init__(self,name,age,sex)
super(OldboyStudent,self).__init__(name,age,sex,)
self.stu_id=stu_id
def choose_course(self):
print('%s is choosing course' %self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, sex, level):
# OldboyPeople.__init__(self,name,age,sex)
super(OldboyTeacher,self).__init__(name,age,sex)
self.level=level
def score(self,stu,num):
stu.score=num
print('老师[%s]为学生[%s]打分[%s]' %(self.name,stu.name,num))
"""
2.菱形继承
'''
1、菱形继承
当一个子继承多个父类时,多个父类最终继承了同一个类,称之为菱形继承
2、菱形继承的问题:
python2区分经典类与新式类,如果子的继承是一个菱形继承,那么经典类与形式的区别为?
经典类下查找属性:深度优先查找
新式类下查找属性:广度优先查找
'''
class G(object):
# def test(self):
# print('from G')
pass
class E(G):
# def test(self):
# print('from E')
pass
class B(E):
# def test(self):
# print('from B')
pass
class F(G):
# def test(self):
# print('from F')
pass
class C(F):
# def test(self):
# print('from C')
pass
class D(G):
# def test(self):
# print('from D')
pass
class A(B,C,D):
def test(self):
print('from A')
# pass
obj=A()
print(A.mro())
# obj.test() #A->B->E-C-F-D->G-object
3.多态
""
1 什么是多态
多态指的是同一种事物的多种形态
水-》冰、水蒸气、液态水
动物-》人、狗、猪
2 为和要用多态
多态性:
继承同一个类的多个子类中有相同的方法名
那么子类产生的对象就可以不用考虑具体的类型而直接调用功能
3 如何用
"""
#多态性继承同一个类的多个子类中有相同的方法名
# 第一个版本:
"""
class Animal:
def speek(self):
pass
def eat(self):
pass
class People(Animal):
def speak(self):
print('say hello')
def eat(self):
pass
class Dog(Animal):
def speak(self):
print('汪汪汪')
def eat(self):
pass
class Pig(Animal):
def speak(self):
print('哼哼哼')
peo1=People()
dog1=Dog()
pig1=Pig()
peo1.speak()
dog1.speek()
pig1.speak()
"""
#可以限定父类的标准,强制子类必须使用相同的speak方法名
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self):
print('animal joiao')
@abc.abstractmethod
def eat(self):
pass
class People(Animal):
def speak(self):
print('say hello')
def eat(self):
pass
class Dog(Animal):
def speak(self):
print('汪汪汪')
def eat(self):
pass
class Pig(Animal):
def speak(self):
print('哼哼哼')
def eat(self):
pass
"""
# 强调第一点:
1.Animal() #强制:父类是用来指定标准的,只是规定一个框架格式,不能被实例化
2.Animal父类中有的方法speak()和 eat子类中也必须要有,名字也必须一致
3.子类中的必要要有和父类一致的函数体标准
"""
#
peo1=People()
dog1=Dog()
pig1=Pig()
#
peo1.speak()
dog1.speak()
pig1.speak()
#实现的目的就是调用时不用考虑是什么物种,直接定义一个函数秩序传动物进去就行
def my_speak(animal):
animal.speak() #动物.speak() 结果就是个子对应的输出值
my_speak(peo1) #只需要传动物进去就行
# 概念延伸理解:我们之前也一直在用多态的概念
l=[1,2,3]
s='hello'
t=(1,2,3)
print(l.__len__())
print(s.__len__())
print(t.__len__())
def len(obj):
return obj.__len__()
print(len(l))
print(len(s))
print(len(t))