python-study-22

复习

上节课复习
    1、__init__方法:用于在调用类时/实例化时自动触发,为对象初始化自己独有的特征
        class People:
            country='China'
            def __init__(self,name,age,sex):
                self.name=name
                self.age=age
                self.sex=sex

            def eat(self):
                self.name
                self.func()


        #实例化:
        #1、创造一个空对象p1
        #2、触发对象下的__init__方法,让后将p1,'egon',18,'male'一同传入
        p1=People('egon',18,'male')

    2、绑定方法:
        在类中定义的函数,类可以使用,但类去调用就是一个普通的函数而已,没有自动传值一说
        但类中定义的函数,其实是给对象用的,而且是绑定给对象用的
        绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数自动传入

        p1.eat()

        强调对象的精髓:
            对象不仅包含一系列数据(自己独有的+与其他对象共有的),还包含专门操作该数据的方法


    3、在python3中统一类与类型的概念
        l=[1,2,3] #l=list([1,2,3])
        l.append(4)

        l1=[4,5,6]
        l1.append(5)

        class Foo:pass

    4、继承
        继承是一种新建类的方式,新建的类称为子类或派生类,被继承成类的称为父类 或超类或基类,
        继承的特性:子类可以“遗传”父类的属性

        用继承的目的就是:减少代码冗余

        class Foo:
            pass

        class Bar(Foo):
            pass

        新式类:继承了object类的类Foo,以及Foo类的子类
        经典类:没有继承object类的类Foo,以及Foo类的子类

        只有在python2中才有经典类,在python3中全为新式类(不继承任何类的类默认就会继承object)

        class Foo(object):
            pass

    5、派生
       在子中定义的新属性称为派生,在使用中,始终以自己有的为准
       class Foo:
            pass

        class Bar(Foo):
            x=1

            def func(self):
                pass


    6、在子类派生出的新方法中重用父类功能
         指名道姓(跟继承无关):类名.函数(全部参数。。。)



今日内容:
    1、组合(*****2、菱形继承问题(新式类vs经典类)(*****3、在子派生的新方法中重用父类功能的两种方式(*****)

    4、多态与多态性(*****)
    5、封装(*****)
View Code

 

组合--对象关联

'''
1、什么是组合
    组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象


2、为何用组合
    组合也是用来解决类与类直接代码冗余问题的

3、如何用组合

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))


stu1=OldboyStudent('猪哥',19,'male',1)
tea1=OldboyTeacher('egon',18,'male',10)

stu1.choose_course()
tea1.score(stu1,100)
print(stu1.__dict__)

'''
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.course=python
tea1.course=linux

stu1.course.tell_info()
tea1.course.tell_info()
View Code

 

菱形继承--属性查找

#coding:utf-8
'''
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
View Code

 

继承中两种重用方法的方式

# 在子派生的新方法中重用父类功能的两种方式
# 方式一:与继承无关
#指名道姓法,直接用:类名.函数名
# 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)


# 方式二:严格依赖继承属性查找关系
# super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性的(按照继承的关系)
# super().__init__(不用为self传值)
# 注意:
# super的完整用法是super(自己的类名,self),在python2中需要写完整,而python3中可以简写为super()
# 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)
#         super(OldboyStudent,self).__init__(name,age,sex)
#         self.stu_id=stu_id
#
#     def choose_course(self):
#         print('%s is choosing course' %self.name)
#
#
# stu1=OldboyStudent('猪哥',19,'male',1)
# print(stu1.__dict__)
#
# print(OldboyStudent.mro())


class A:
    def f1(self):
        print('A.f1')

class B:
    def f2(self):
        super().f1()
        print('B.f2')

class C(B,A):
    pass

obj=C()
print(C.mro()) #C-》B->A->object
obj.f2()
View Code

 

多态--子类 抽象 鸭子类型

'''
1 什么是多态
    多态指的是同一种事物的多种形态
        水-》冰、水蒸气、液态水
        动物-》人、狗、猪

2 为和要用多态
    多态性:
    继承同一个类的多个子类中有相同的方法名
    那么子类产生的对象就可以不用考虑具体的类型而直接调用功能

3 如何用
'''
import abc

class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def speak(self):
        pass
    @abc.abstractmethod
    def eat(self):
        pass

# Animal() #强调:父类是用来指定标准的,不能被实例化

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



peo1=People()
dog1=Dog()
pig1=Pig()
#
#
# peo1.speak()
# dog1.speak()
# pig1.speak()

# def my_speak(animal):
#     animal.speak()
#
# my_speak(peo1)
# my_speak(dog1)
# my_speak(pig1)

#
# l=[1,2,3]
# s='helllo'
# t=(1,2,3)
#
# print(l.__len__())
# print(s.__len__())
# print(t.__len__())
#
# # def len(obj):
# #     return obj.__len__()
#
# print(len(l)) # l.__len__()
# print(len(s)) #s.__len__()
# print(len(t))


# python推崇的是鸭子类型,只要你叫的声音像鸭子,并且你走路的样子也像鸭子,那你就是鸭子

class Disk:
    def read(self):
        print('disk read')

    def write(self):
        print('disk wirte')


class Process:
    def read(self):
        print('process read')

    def write(self):
        print('process wirte')


class File:
    def read(self):
        print('file read')

    def write(self):
        print('file wirte')



obj1=Disk()
obj2=Process()
obj3=File()



obj1.read()
obj1.write()
View Code

 

今日作业:
    1、多重继承的执行顺序,请解答以下输出结果是什么?并解释。

        class A(object):
           def __init__(self):
               print('A')
               super(A, self).__init__()

        class B(object):
           def __init__(self):
               print('B')
               super(B, self).__init__()

        class C(A):
           def __init__(self):
               print('C')
               super(C, self).__init__()

        class D(A):
           def __init__(self):
               print('D')
               super(D, self).__init__()

        class E(B, C):
           def __init__(self):
               print('E')
               super(E, self).__init__()

        class F(C, B, D):
           def __init__(self):
               print('F')
               super(F, self).__init__()

        class G(D, B):
           def __init__(self):
               print('G')
               super(G, self).__init__()

        if __name__ == '__main__':
           g = G()
           f = F()

    2、什么是新式类,什么是经典类,二者有什么区别?什么是深度优先,什么是广度优先?
    3、解释多态、多态性、鸭子类型
    4、定义课程类、班级类、老师类、学生类,要求如下
        1、一名老师可以带多个班级,一名学生可以属于多个班级
        2、班级绑定课程
        3、基于继承或组合减少代码冗余

    选做:按照图,实现其他类及其关系
作业
##1
# class A(object):
#     def __init__(self):
#         print('A')
#         super(A, self).__init__()
#
#
# class B(object):
#     def __init__(self):
#         print('B')
#         super(B, self).__init__()
#
#
# class C(A):
#     def __init__(self):
#         print('C')
#         super(C, self).__init__()
#
#
# class D(A):
#     def __init__(self):
#         print('D')
#         super(D, self).__init__()
#
#
# class E(B, C):
#     def __init__(self):
#         print('E')
#         super(E, self).__init__()
#
#
# class F(C, B, D):
#     def __init__(self):
#         print('F')
#         super(F, self).__init__()
#
#
# class G(D, B):
#     def __init__(self):
#         print('G')
#         super(G, self).__init__()
#
#
# print(F.mro())
# print(G.mro())
# if __name__ == '__main__':
#     g = G()  # GDAB
#     f = F()  # FCBDA

    # [<class '__main__.F'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>]
    # [<class '__main__.G'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

##2
#向上能回溯到object就是新式类 否则是经典类 p3都是新式类 p2既有新式类又有经典类
#新式类用广度优先,经典类用深度优先  属性查找算法

##3
# 多态指的是同一事物的多种形态
# 继承同一个父类的多个子类中有相同的方法名,那么子类产生的对象就可以不用考虑具体的类型而直接调用功能
#独立的类 方法名相同

##4

class Classes:
    def __init__(self,name,semester='1',date='5.23',teacher='egon'):
        self.name=name
        self.semester=semester
        self.date=date
        self.teacher=teacher

    def tell_info(self):
        msg="""
        班级名:%s
        学期:%s
        开课日期:%s
        班主任:%s
        """ %(self.name,self.semester,self.date,self.teacher)
        print(msg)

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
        self.cla = []

    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
        self.cla=[]

    def score(self,stu,num):
        stu.score=num
        print('老师[%s]为学生[%s]打分[%s]' %(self.name,stu.name,num))

#创造班级
sh_py1 = Classes('sh_oldboy1')
sh_lin1=Classes('sh_oldboy2')

# 创造课程
python=Course('python全栈开发','5mons',3000)
linux=Course('linux运维','5mons',800)

#班级和课程绑定
sh_py1.course=python
sh_lin1.course=linux

#创造老师和学生
stu1=OldboyStudent('猪哥',19,'male',1)
tea1=OldboyTeacher('egon',18,'male',10)

#学生和老师与班级绑定
stu1.cla.append(sh_py1)
stu1.cla.append(sh_lin1)
tea1.cla.append(sh_lin1)

for i in stu1.cla:
    i.tell_info()     #查看班级信息
    i.course.tell_info() #查看课程信息
View Code

 

posted @ 2018-06-27 15:43  xujinjin  阅读(155)  评论(0编辑  收藏  举报