一、面向对象编程
三大特性:封装、继承、多台。一切皆对象,把一个类变成 一个具体对象的具体过程叫实例化(初始化一类,造了一个对象)
1.封装
类中的函数:
(1)构造函数:
在实例化时做一些类的初始化的工作,将实例的属性存入内存
(2)类的方法:
类的功能(动态属性)
(3)析构函数:
def __del__(self):
析构函数:在实例释放、销毁(程序结束)的时候自动执行的,通常用于做一些收尾工作,如关闭一些数据库连接或关闭打开的临时文件等
注意:为何有self?
调用函数 -》 执行 -》 返回结果
实例化的时候 在一般思维下 应该是这种方式:r1 = Role.init(…,…) return x3434(内存地址)
实际上是这种方式:
r1=Role(r1,“alex”,“police”,“15000”)
r1.name=…
实例化用文字描述就是 先给类传值,类去开辟一块新内存,类往里面存传过来的值,同时r1也传进去了(__init__函数),因为类要让r1把参数记录下,所以
就把r1传进去,给r1赋值(实例化)
在调用类的方法时 比如r1.buy_gun() 相当于就是Role.buy_gun(r1) 因为要告诉类是谁在调用方法才好把函数的结果传给谁,所以
类的每个方法必须至少传入这个实例化的对象,且实例化调用的方法是类内存里的函数。
注意:调用实例的属性时,先在实例里找,找不到再到类里面找
(4)类的变量:
类变量:所有实例共用的属性
实例变量(静态属性),作用域就是实例本身
(5)类的私有属性、私有方法:
只能类内部访问,不能外部访问与继承
#!/usr/bin/env python
# coding:utf-8
# Author:Yang
class Role(object):
n=123 # 类变量
name = "我是类name"
def __init__(self,name,role,weapon,life_value=100,money=15000): # 将属性存入内存
# 构造函数
# 在实例化时做一些类的初始化的工作
self.name=name # 实例变量(静态属性),作用域就是实例本身
self.role=role
self.weapon=weapon
self.__life_value=life_value # 私有属性
self.money=money
# 类的方法,功能(动态属性)
def got_shot(self):
print("i got shot")
def buy_gun(self,gun_name):
print("%s just buy %s"%(self.name,gun_name))
# 析构函数:在实例释放、销毁(程序结束)的时候自动执行的,通常用于做一些收尾工作,如关闭一些数据库连接或关闭打开的临时文件等
def show_status(self):
print("name:%s life_value:%s"%(self.name,self.__life_value))
def __shot(self):# 私有方法
pass
def __del__(self):
print("%s 彻底死了..."%self.name)
r1=Role("yang","police","ak47") # 把一个类变成一个具体对象的过程叫实例化(初始化一个类,造了一个对象)
r1.buy_gun("ak47") # r1又叫做Role的实例
r2=Role("hao","terrorist","awm")
print(Role.name)
print(r2.n,r2.name)
r1.bullet_prove=True # 增加
# del r1.bullet_prove # 删除
print(r1.n,r1.name,r1.bullet_prove) # 先找实例本身,再到类里面找
r1.n="改的类变量"
print(r1.n)
# 所谓的改类变量 相当于是在实例内存里创建一个新n
print(r2.n) # 所以r2内存里没n,就去类的内存里找
print(r1.show_status())# 私有属性只能在类内部访问,不能在外部访问
# 为何有self?:
# 调用函数 -》 执行 -》 返回结果
# 实例化的时候 在一般思维下 应该是这种方式:r1 = Role.__init__(..,...) return x3434(内存地址)
# 实际上是这种方式:
# r1=Role(r1,"alex","police","15000")
# r1.name=...
# 用文字描述就是 先给类传值,类去开辟一块新内存,类往里面存传过来的值,同时r1也传进去了(__init__函数),因为类要让r1把参数记录下,所以
# 就把r1传进去,给r1赋值(实例化)
# 在调用类的方法时 比如r1.buy_gun() 相当于就是Role.buy_gun(r1) 因为要告诉类是谁在调用方法才好把函数的结果传给谁,所以
# 类的每个方法必须至少传入这个实例化的对象,且实例化调用的方法是类内存里的函数。
# 类变量的作用:所有实例共用的属性
2.继承
继承就是子类继承父类的方法,并且子类能够扩展自己的功能
定义类时 class A: 是经典类的继承方法
class A(object):是新式类的继承方法 object是一切类的父类
继承可以对构造函数进行重构,从父类中继承的参数由父类实现,新加的参数由自身实现
注意有两种方法写构造函数
比如 class B(A):
def __ init (self,x,y,z):
第一种:A. init (x,yxz)
第二种 :super(B,self). init __ (x,y)
self.z=z(推荐使用第二种) 注意:super 是新式类的写法
class Man(People): # 继承people
def __init__(self,name,age,money): # 对构造函数进行重构(man多加参数) name,age在父类实现(所有默认参数都要写),money在子类实现
# People.__init__(self,name,age) 第一种方法
super(Man, self).__init__(name,age) # 第二种方法 super去继承父类构造函数 优点:当people改变时在字方法里不用写people,多继承时只用写一个super
self.money=money # super是新式类的写法 当多继承时 super只写一个是因为只有继承一个构造方法__init__
print("%s 元"%money)
单继承:
#!/usr/bin/env python
# coding:utf-8
# Author:Yang
# class People:经典类
class People(object): # 新式类 多继承方式变了
def __init__(self,name,age):
self.name=name
self.age=age
def eat(self):
print("%s is eating.."%self.name)
def sleep(self):
print("%s is sleeping.."%self.name)
def talk(self):
print("%s is talking.."%self.name)
def __fuck(self): # 私有方法继承不了
pass
class Relation(object):
def make_friends(self,obj): #
print("%s is making friends with %s"%(self.name,obj.name))
self.friends.append(obj.name)
class Man(People): # 继承people
def __init__(self,name,age,money): # 对构造函数进行重构(man多加参数) name,age在父类实现(所有默认参数都要写),money在子类实现
# People.__init__(self,name,age) 第一种方法
super(Man, self).__init__(name,age) # 第二种方法 super去继承父类构造函数 优点:当people改变时在字方法里不用写people,多继承时只用写一个super
self.money=money # super是新式类的写法 当多继承时 super只写一个是因为只有继承一个构造方法__init__
print("%s 元"%money)
def piao(self):
print("%s is piaoing.."%self.name)
def sleep(self):
People.sleep(self)
print("man is sleeping")
class Woman(People,Relation): # 多继承people、Realtion 当ralation里没构造方法时去people里找,不管relation在前还是在后,但relation和people都有__init__时只找最左边的那个
def get_birth(self):
print("%s is born a baby.."%self.name)
m1 = Man("yang",22,10)
m1.eat()
m1.sleep()
m1.talk()
m1.piao()
w1 = Woman("A",22)
w1.eat()
w1.sleep()
w1.get_birth()
w1.make_friends(m1)
多继承:
python可以支持多继承,java不能支持多继承
多继承区别
对于构造函数的查找
有两种继承策略:
比如 :D继承B、C ,B、C继承A
广度优先:横向策略查找优先 D->B->C->A 实线
深度优先:纵向策略查找优先 D->B->A->C 虚线
python3 经典类和新式类都是广度优先来继承的
Python2 经典类是深度优先来继承的,新式类是广度优先来继承的
例如 class C(B,A):
先从B里找构造方法 找不到 去A里,当两者都有构造方法的时候,只找最左边的那个
#!/usr/bin/env python
# coding:utf-8
# Author:Yang
# 多继承区别
# 对于构造函数的查找
# 有两种继承策略:
# 广度优先:横向策略查找优先 D->B->C->A
# 深度优先:纵向策略查找优先 D->B->A->C
# python3 经典类和新式类都是广度优先来继承的
# Python2 经典类是深度优先来继承的,新式类是广度优先来继承的
class A :
def __init__(self):
print("A")
class B(A):
pass
# def __init__(self):
# print("B")
class C(A):
pass
# def __init__(self):
# print("C")
class D(B,C):
pass
d1=D()
3.多态:
多态就是痛一种接口多种实现
注意 python没有直接语法支持多态,但是可以间接实现多态
#!/usr/bin/env python
# coding:utf-8
# Author:Yang
class Animal:
def __init__(self,name):
self.name=name
def talk(self):
pass
@staticmethod
def animal_talk(obj): # 一种接口 多种实现
obj.talk()
class Cat(Animal):
def talk(self):
print( "Meow")
class Dog(Animal):
def talk(self):
print( "Woof")
d=Dog("yang")
# d.talk()
# animal_talk(d)
c=Cat("hao")
# c.talk()
# animal_talk(c)
# python 没有直接语法支持多态,但是可以间接
Animal.animal_talk(c) # 多态:同一种接口,多种实现
Animal.animal_talk(d)