面向对象

面向过程

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

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

缺点:可扩展性差

面向对象

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

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

优点:可扩展性高

缺点:极易出现过度设计

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

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

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

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

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
原文地址:https://www.cnblogs.com/Ryans-World/p/7372082.html