python基础之面向对象
面相对象
----------------------------------------------------------------------------------------------------------------
定义:具有相同属性和方法的一类事物就是类,对象是类中一个具体的列子是对象实例
由类创建对象的过程
那什么是类,什么是对象,什么是实例,什么是实例化?
类:具有相同属性和方法的一类事物(框架,模子) , 命名空间是方法和(静态属性字段)
对象:对象是类中一个具体的例子(拥有具体的属性值和具体的方法),命名空间是类指针对象的所有属性
实例:实例完全和对象一样
实例化:是由类创建对象的过程
类名能做什么?
1.实例化
2.调用类中的静态属性
实例化的过程:对象名==类名(参数)
1.创建一个属于对象的空间
2.将这个空间的地址和参数传递给__init__方法
3执行init方法
4.将对象的空间返回给对象名
对象能做什么?
1存储在实例化之后创建的空间中的所有变量都是对象的属性
2.每一次实例化产生的空间都是独立的,每一个对象都有自己的属性值
类有两个属性:静态属性和动态属性
类的两个作用:属性引用和实例化
属性引用(类名属性)
class Person: #定义一个人类 role = 'person' #人的角色属性都是人 def walk(self): #人都可以走路,也就是有一个走路方法 print("person is walking...") print(Person.role) #查看人的role属性 print(Person.walk) #引用人的走路方法,注意,这里不是在调用
实例化
class A: role='人' def __init__(self,name): self.name=name def walk(self): print('我要飞得更高') a=A('路飞') #实例化一个对象 print(a.walk()) # 调用方法
静态属性:所有的这个类的对象都共有的属性
动态属性:定义在类中的函数,自带一个self,就是调用这个方法的对象本身.
from math import pi class Circle: ------类类名 def__init__(self,r): ------对象实例 self.r=r def zc (self): return 2*pi*self.r def mj (self): return pi*self.r**2 a=Circle(5) ----实例化 print(a.zc())
面向过程:
优点:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可.
缺点:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身
应用场景:一但完成基本很少改变的场景,著名的例子有Linux内核,git,以及Apache HTTP Server等
面向对象:
优点:解决了程序的扩展性.对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易
缺点:可控性差,无法像面向过程的程序设计l流水线式的可以很准确的预测问题的处理流程,面向对象的程序一旦开始就由对象之间的交互解决问题,即使是上帝也无法预测结果.
应用场景:需求经常变化的软件,一般需求的变化都集中在用户端,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方.
对象之间的交互:
class Person: # 定义一个人类 role = 'person' # 人的角色属性都是人 def __init__(self, name, aggressivity, life_value): self.name = name # 每一个角色都有自己的昵称; self.aggressivity = aggressivity # 每一个角色都有自己的攻击力; self.life_value = life_value # 每一个角色都有自己的生命值; def attack(self,dog): # 人可以攻击狗,这里的狗也是一个对象。 # 人攻击狗,那么狗的生命值就会根据人的攻击力而下降 dog.life_value -= self.aggressivity class Dog: # 定义一个狗类 role = 'dog' # 狗的角色属性都是狗 def __init__(self, name, breed, aggressivity, life_value): self.name = name # 每一只狗都有自己的昵称; self.breed = breed # 每一只狗都有自己的品种; self.aggressivity = aggressivity # 每一只狗都有自己的攻击力; self.life_value = life_value # 每一只狗都有自己的生命值; def bite(self,people): # 狗可以咬人,这里的狗也是一个对象。 # 狗咬人,那么人的生命值就会根据狗的攻击力而下降 people.life_value -= self.aggressivity egg = Person('egon',10,1000) #创造了一个实实在在的人egg ha2 = Dog('二愣子','哈士奇',10,1000) #创造了一只实实在在的狗ha2 print(ha2.life_value) #看看ha2的生命值 egg.attack(ha2) #egg打了ha2一下 print(ha2.life_value) #ha2掉了10点血
面向对象的组合用法:
1.教授的生日,有的关系
class BirthDate: def __init__(self,year,month,day): self.year=year self.month=month self.day=day class Couse: def __init__(self,name,price,period): self.name=name self.price=price self.period=period class Teacher: def __init__(self,name,gender,birth,course): self.name=name self.gender=gender self.birth=birth self.course=course def teach(self): print('teaching') p1=Teacher('egon','male', BirthDate('1995','1','27'), Couse('python','28000','4 months') ) print(p1.birth.year,p1.birth.month,p1.birth.day) print(p1.course.name,p1.course.price,p1.course.period) ''' 运行结果: 1 27 python 28000 4 months '''
第二种方法:用圆来求出圆环
from math import pi class Circle: ''' 定义了一个圆形类; 提供计算面积(area)和周长(perimeter)的方法 ''' def __init__(self,radius): self.radius = radius def area(self): return pi * self.radius * self.radius def perimeter(self): return 2 * pi *self.radius circle = Circle(10) #实例化一个圆 area1 = circle.area() #计算圆面积 per1 = circle.perimeter() #计算圆周长 print(area1,per1) #打印圆面积和周长 class Ring: ''' 定义了一个圆环类 提供圆环的面积和周长的方法 ''' def __init__(self,radius_outside,radius_inside): self.outsid_circle = Circle(radius_outside) self.inside_circle = Circle(radius_inside) def area(self): return self.outsid_circle.area() - self.inside_circle.area() def perimeter(self): return self.outsid_circle.perimeter() + self.inside_circle.perimeter() ring = Ring(10,5) #实例化一个环形 print(ring.perimeter()) #计算环形的周长 print(ring.area()) #计算环形的面积
import pickle class Course: def __init__(self,name,price): self.name=name self.price=price class Student: def __init__(self,name,price): self.name = name self.price = price python=Course('python',19800) with open('Courses','wb') as f: pickle.dump(python,f) with open('Courses','rb')as f: pickle.load(f) print(Course)
定义:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方法式去表达出抽象的结构
java:不支持多继承
python:支持多继承,通过抽象类的多继承来实现复杂的规范
继承的作用:
1)减少代码的重用
2)提高代码可读性
3)规范编码模式
继承有两种语法:
单继承和多继承
基础概念
父类: 超类基类
子类:派生类
子类使用父类的方法:
1)子类中油,父类中没有:用子类
2)子类中没有,父类中有:用父类
3)子类父类中都有:默认情况下用子类的||||既又想用父类,又想用子类: 1)父类方法.方法名(子类对象)
2)super().方法名()
4)都没有就报错
归一化设计-------------obj
class A: def eat()self): pass class B : def eat(self): pass def eat(obj): obj.eat()
定义:抽象类是一个特殊的类,他的特殊之处在于只能被继承,不能被实例化
抽象类主要就是作为基类/父类,来约束子类中必须实现的某些方法
特点:
---------1必须在类定义的时候指定metaclass=ABCMeta
----------2必须在要约束的方法上方加@abstractmethod 方法
from abc import ABCMeta,abstractmethod #(抽象方法) class Payment(metaclass=ABCMeta): # metaclass 元类 metaclass = ABCMeta表示Payment类是一个规范类 @abstractmethod # @abstractmethod表示下面一行中的pay方法是一个必须在子类中实现的方法 def pay(self):pass @abstractmethod def back(self):pass # 退款功能 class AliPay(Payment): def __init__(self,name): self.name = name def pay(self,money): # 支付宝提供了一个网络上的联系渠道 print('%s通过支付宝消费了%s元'%(self.name,money)) def back(self): print('退款') class WeChatPay(Payment): def __init__(self,name): self.name = name def pay(self,money): # 微信提供了一个网络上的联系渠道 print('%s通过微信消费了%s元'%(self.name,money)) def back(self): print('退款') class ApplePay(Payment): def __init__(self,name): self.name = name def pay(self,money): print('%s通过苹果支付消费了%s元'%(self.name,money)) def back(self): print('退款') # 归一化设计 : 从原来的面向对象编程 -->面向函数编程.降低了用户的使用成本 def pay_func(person,payway,money): if payway == 'alipay': per = AliPay(person) elif payway == 'wechatpay': per = WeChatPay(person) elif payway == 'ApplePay': per = ApplePay(person) per.pay(money) pay_func('lufei','alipay',200) pay_func('nazha','wechatpay',100)
定义:接口只是定义了一些方法,而没去实现,多用于程序设计时,只是设计需要有什么样的功能,但是并没有实现任何功能
接口类: 其实跟抽象类几乎一样
1)python中由于有了抽象类的多继承,不需要接口的概念了
2)一个基类写出来被子类继承了:接口类
3)并且在方法中只写pass(你可以选择性的满足)
接口提取了一群类共同的函数,可以把接口当做一个函数的集合。
然后让子类去实现接口中的函数。
这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。
归一化,让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。
比如:我们定义一个动物接口,接口里定义了有跑、吃、呼吸等接口函数,这样老鼠的类去实现了该接口,松鼠的类也去实现了该接口,由二者分别产生一只老鼠和一只松鼠送到你面前,即便是你分别不到底哪只是什么鼠你肯定知道他俩都会跑,都会吃,都能呼吸。
再比如:我们有一个汽车接口,里面定义了汽车所有的功能,然后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田,还是奥迪,还是大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样