zoukankan      html  css  js  c++  java
  • 面向对象

    面向过程

    核心是过程,过程指的是问题的解决步骤,即先干什么再干什么,基于面向过程去设计程序就好比设计一条流水线,是一种机械式的思维方式

    优点:复杂的问题流程化,进而简单化

    缺点:可扩展性差

    面向对象

    核心是对象,对象就是特征与技能的结合体,如果把设计程序比喻成创造一个世界,那你就是这个世界的上帝,与面向过程对机械流水线的模拟形成鲜明的对比,

    面向对象更加注重的是对现实世界的模拟

    优点:可扩展性高

    缺点:极易出现过度设计

    一系列对象相似的特征与技能的结合体

    在现实世界中,先有一个个具体存在的对象,随着发展,总结相似之处,得到现实中的类

    在程序中,一定是先定义类,后调用类来产生对象

    第一阶段:由现实中的对象,总结出现实中的类

    obj1:
        特征
             学校=oldboy
             名字=李
             年龄=18
             性别=女
        技能
            学习
            吃饭
    obj2:
        特征
             学校=oldboy
             名字=张
             年龄=28
             性别=男
        技能
            学习
            吃饭
    obj3:
        特征
             学校=oldboy
             名字=牛
             年龄=18
             性别=女
        技能
            学习
            吃饭

    类就是现实中的老男孩学生类:

       相似的特征
            学校=oldboy
        相似的技能
            学习
            吃饭

    第二阶段:程序中的类产生程序中的对象

    class OldboyStudent:           # 定义了类,类体中的代码在类定义阶段就会执行
        school = 'oldboy'      # 特征 ,类的数据属性
        def learn(self):         # 技能,类的函数属性
            print('is learning')
        def eat(self):
            print('is eating')
     
    print(OldboyStudent.__dict__)     # 查看类的 名称空间(用来存放类中的变量名和函数名)
    #通过字典访问里面的属性
    print(OldboyStudent.__dict__['school'])
    print(OldboyStudent.__dict__['learn'])
    #python提供了访问属性的语法
    print(OldboyStudent.school)
    print(OldboyStudent.learn)
    OldboyStudent.learn(123)
    #新增属性
    OldboyStudent.x=11111
    OldboyStudent.school='Oldboy'
    print(OldboyStudent.__dict__)
    #删除属性
    del OldboyStudent.school
    print(OldboyStudent.__dict__)

    对象

    如何产生程序中的对象?类名加括号,调用类,产生一个该类的实际存在的对象,该过程称为实例化,产生的结果又可以称为实例

    obj1=OldboyStudent()
    obj2=OldboyStudent()
    obj3=OldboyStudent()

    产生了3个相同的对象,因为并没有使用__init__()

    class OldboyStudent:          
        school = 'oldboy'      
        def __init__(self,name,age,sex):   # 只在实例化的时候执行,在对象产生之后才会执行
            if not isinstance(name,str):
                raise TypeError('名字必须是字符串类型')
            self.name=name
            self.age=age
            self.sex=sex
        def learn(self):       
            print('%s is learning' % self.name)
        def eat(self):
            print('is eating')
     
    obj1=OldboyStudent('',18,'')
    #两步:1.先生成一个空对象 2.连同空对象和后面的三个参数,组成一组(obj1,'李',18,'女')传给__init__(),相当于 OldboyStudent.__init__(obj1,'李',18,'女')
    print(obj1.name)  # obj1.__dict__['name']
    obj1.name=''
    print(obj1.name)
     
    print(obj1.school,id(obj1.school))
    print(obj2.school,id(obj2.school))
    print(obj3.school,id(obj3.school))
    print(OldboyStudent.school,id(OldboyStudent.school))
    #以上4个完全相同,就是同一个 
    #对象可以访问类的数据属性,类的数据属性是共享给所有对象使用的,id都一样
     
    #类的函数属性
    OldboyStudent.learn(obj1)
    print(obj1.learn)   #绑定方法
    print(OldboyStudent.learn)   # 函数属性
     
    obj1.learn()   # OldboyStudent.learn(obj1)  
    #绑定方法的特殊之处在于,绑定给谁,就由谁来调用,谁来调用,就把谁当作第一个参数传入

    统计

    class Foo:
        count=0
        def __init__(self,x,y,z):
            self.x=x
            self.y=y
            self.z=z
            Foo.count+=1
    
    obj1=Foo(1,1,1)
    obj2=Foo(1,2,1)
    obj3=Foo(1,2,3)
    print(obj1.count)
    print(Foo.count)

    对象之间的交互

    class Garen:
        camp='Demacia'
        def __init__(self,nickname,life_value=100,aggresivisity=80):
            self.nickname=nickname
            self.aggresivity=aggresivity
        def attack(self,enemy):
            enemy.life_value-=self.aggresivity
    
    class Riven:
        camp='Noxus'
        def __init__(self,nickname,life_value=80,aggresivisity=100):
            self.nickname=nickname
            self.aggresivity=aggresivity
        def attack(self,enemy):
            enemy.life_value-=self.aggresivity
    
    g1=Garen('草丛')
    r1=Riven('')
    print(r1.life_value)
    g1.attack(r1)
    print(r1.life_value)

    继承

    1.解决代码重用问题

    2.继承是类与类之间的关系,是一种,什么是什么的关系

    3.在子类派生出新的方法内重用父类功能的方式:指名道姓法

    OldboyPeople.__init__()

    这种调用方式本身与继承没有关系

    class ParentClass1:
        pass
    class ParentClass2:
        pass
    class SubClass1(ParentClass1):
        pass
    class SubClass2(ParentClass1,ParentClass2):
        pass
    
    print(SubClass1.__bases__)
    print(SubClass2.__bases__)
    print(ParentClass1.__bases__) #python3的基类默认继承object,这是经典类与新式类的区别
    #查看父类
    class OldboyPeople:
        school='oldboy'
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
        def eat(self):
            print('is eating')
    
    class OldboyStudent(OldboyPeople):
        def learn(self):
            print('%s is learning'  % self.name)
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self,name,age,sex,salary,title):
            OldboyPeople.__init__(self,name,age,sex):
            self.salary=salary
            self.title=title
        def teach(self):
            print('%s is teaching' % self.name)
     
    obj1=OldboyStudent('tom',23,'female')
    egon_obj=OldboyTeacher('egon',23,3000,'沙河讲师')

    组合

     

    class OldboyPeople:
        school='oldboy'
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
        def eat(self):
            print('is eating')
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self,name,age,sex,salary,title):
            OldboyPeople.__init__(self,name,age,sex)
            self.salary=salary
            self.title=title
            self.course=[]
        def teach(self):
            print('%s is teaching' % self.name)
    
    class Course:
        def __init__(self,course_name,course_period,course_price):
            self.course_name=course_name
            self.course_period=course_period
            self.course_price=course_price
        def tell_info(self):
            print('<课程名:%s 周期:%s 价格:%s>' % (self.course_name,self.course_period,self.course_price))
    
    python=Course('Python','6month',3000)
    linux=Course('Linux','3month',2000)
    bigdata=Course('Bigdata','1month',1000)
    
    egon_obj=OldboyTeacher('egon',18,'male',3000,'沙河讲师')
    egon_obj.course.append(python)
    egon_obj.course.append(linux)
    
    for obj in egon_obj.course:
        obj.tell_info()
    
    yl_obj=OldboyStudent('',15,'male')
    yl_obj.course.append(python)
    
    for i in yl_obj.course:
        i.tell_info()

    绑定方法与非绑定方法

    1.绑定给谁,谁来调用就自动将它本身当作第一个参数传入

    2.绑定到对象的方法前面已经写了

    绑定到类的方法

    #settings.py
    HOST='192.168.0.1'
    PORT=3307
    import settings
    import uuid
    
    class MySql:
        def __init__(self,host,port):
            self.host=host
            self.port=port
            self.id=self.create_id()        #每产生一个对象就赋予一个唯一的id
     
        #def func1():pass
        #def func2(self):pass
        #上面两种都是给对象用的,并且def func():pass是一种错误的方法 
    
        @classmethod       #绑定给类
        def from_conf(cls):  # cls就是这个类,函数内部的不需要对象,需要的是类
            return cls(settings.HOST,settings.PORT)
        def func1(self):     #绑定给对象
            pass
        @staticmethod   和谁都没有关系,就是一个普通函数,工具,不与任何对象绑定
        def create_id():   #函数内既不需要类也不需要对象,就定义成非绑定方法
            return str(uuid.uuid1())
    
    conn1=MySql('127.0.0.1',3306)     #实例化传入
    conn2=MySql.from_conf()        #配置文件中取出
    print(conn1.host,conn2.host)
    #和对象没有关系就定义成类方法
    
    conn3=MySql('127.0.0.1',3306)
    conn4=MySql('127.0.0.2',3307)
    conn5=MySql('127.0.0.3',3308)
    print(conn3.id,conn4.id,conn5.id)

    继承实现原理

    单继承

    class A:
        def f1(self):
            print('A.f1')
        def f2('A.f2'):
            print('A.f2')
            self.f1()        # b.f1()
    
    class B(A):
        def f1(self):
            print('B.f2')
    
    b=B()
    b.f2()
    
    #A.f2
    #B.f2

    多继承

    class A:
        def test(self):
            print('A')
    class E:
        def test(self):
            print('E')
    class H:
        def test(self):
            print('H')
    class G(H):
        def test(self):
            print('G')
    class B(A):
        def test(self):
            print('B')
    class D(E):
        def test(self):
            print('D')
    class F(G):
        def test(self):
            print('F')
    class C(B,D,F):
        def test(self):
            print('C')
    
    print(C.mro())  # 查看C类的继承关系

    super()

    子类的方法重用父类的功能

    class OldboyPeople:
        school='oldboy'
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
        def eat(self):
            print('is eating')
        def teach(self):
            print('这是父类的teach')
    class OldboyTeacher(OldboyPeople):
        def __init__(self,name,age,sex,salary,title):
            #OldboyPeople.__init__(self,name,age,sex)  # 指名道姓,与继承无关
            #super(OldboyTeacher,self).__init__()    #适用于python2
            print(super().school)     # oldboy
            print(super().eat)
            super().__init__(name,age,sex)
            self.salary=salary
            self.title=title
        def teach(self):
            #OldboyPeople.teach(self)
            super().teach()
            print('%s is teaching' % self.name)
    
    print(OldboyTeacher.mro())
    egon_obj=OldboyTeacher('egon',18,'male',300,'沙河将讲师')
    print(egon_obj.title)
    print(egon_obj.__dict__)
    egon_obj.teach()
    class A:
        def test(self):
            super().test()  
    classB:
        def test(self):
            print('B')
    class C(A,B):
        pass
    
    c=C()
    c.test()     #并不会发生报错,因为super是只看C类的mro列表,并不是看到A类的父类object没有test方法就会报错
    #B
  • 相关阅读:
    [Aaronyang] 写给自己的WPF4.5 笔记23 [3d交互与动画 4/4]
    [Aaronyang] 写给自己的WPF4.5 笔记22 [3d交互与动画 3/4]
    [Aaronyang] 写给自己的WPF4.5 笔记21 [3d课 2/4]
    [Aaronyang] 写给自己的WPF4.5 笔记20 [3d课 1/4]
    [Aaronyang] 写给自己的WPF4.5 笔记19[Visual类图文并茂讲解]
    [Aaronyang] 写给自己的WPF4.5 笔记18[几何图形*Geometry图文并茂讲解]
    [Aaronyang紫色博客] 写给自己的WPF4.5-Blend5公开课系列 3
    [Aaronyang紫色博客] 写给自己的WPF4.5-Blend5公开课系列 2-更进一步
    [Aaronyang紫色博客] 写给自己的WPF4.5-Blend5公开课系列 1
    [Aaronyang] 写给自己的WPF4.5 笔记15[AyArc诞生-WPF版本绚丽的环状图,Ay制作,AyWindow强势预览]
  • 原文地址:https://www.cnblogs.com/Ryans-World/p/7372082.html
Copyright © 2011-2022 走看看