类(class)
属性
实例变量(每个实例内存中)
类变量(类内存中)
私有属性 __var
方法
构造方法
析构函数(默认就有,代码为空,写了则相当于重构它)
对象(object):类的实例(实例化一个类之后得到的对象)
封装:
把一些功能的实现细节不对外暴露
继承:
(先覆盖、再继承、再添加)
代码复用
单继承
多继承
2.7 经典类 深度优先
新式类 广度优先
3.x 均广度优先
多态:
接口重用(一种接口,多种实现)
继承方式:
继承
组合
编程范式:(一组指令的集合,实现方式)
编程是 程序 员 用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 , 一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种不同的方式,对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式。
面向过程
使用一系列的指令告诉计算机一步一步的做什么
就是程序从上到下一步步执行,一步步从上到下,从头到尾的解决问题 。基本设计思路就是程序一开始是要着手解决一个大的问题,然后把一个大问题分解成很多个小问题或子过程,这些子过程再执行的过程再继续分解直到小问题足够简单到可以在一个小步骤范围内解决。
面向对象介绍
世界万物,皆可分类
世界万物,皆为对象
只要是对象,就肯定属于某种品类
只要是对象,就肯定有属性
现实生活中就是这个样子的,面向对象就是按照现实生活的这个规则
面向对象是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。
面向对象特性:
Class类: (属性)# 例如:鸟的属性
类即是对一类相同属性的对象的抽象、蓝图、原形。
Object对象:(实例)# 例如:一个具体的鸟
一个对象即是一个类实例化后的实例
三大特性:
封装:
再类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法。比如人的消化系统、心脏、等封装
继承:一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
多态:是面向对象的重要特性,简单点说:“一个接口,多种实现”,提供统一接口
面向过程编程与面向的主要区别就是面向对象可以使程序更加容易扩展和易更改。
定义类:(object 所有类的父类)
class Dog(object): # 定义一个类, class是定义类的语法,Role是类名,(object)是新式类的写法
n = 123 # 类变量
def __init__(self,name): # 构造函数--传参数用
# 作用:在实例化时做一些累的初始化的工作。
self.name = name # 实例变量(静态属性),赋给实例
# 实例变量作用域就是实例本身
def bulk(self) # 类的方法(动态属性),功能
print("%s wang wang!" % self.name)
创建实例(对象):
# 通过一个类创建一个具体对象的过程叫 实例化
dog1 = Dog("wangcai") # 创建实例,并赋值给变量
# dog1 是对象,又叫Dog这个类的实例
dog1.bulk() # 调用内部方法
初始化一个实例,就需要调用这个类一次:
dog1 = Dog("wangcai") # 生成一个实例,会自动把参数传给Dog下面的__init__(...)方法
上面创建dog1对象的时候,并没有给self传值,程序也没未报错,是因为,类在调用它自己的__init__构造函数时已经帮你给self参数赋值了
dog1 = Dog("wangcai") # 此时self 相当于 dog1 , dog1 = Dog(dog1, "wangcai")
当执行dog1 = Dog(“wangcai”)时,python的解释器其实干了两件事:
def bulk(self)
print("%s wang wang!" % self.name)
上面这个方法通过类调用的话要写成如下:
dog1 = Dog("wangcai")
dog1.bulk() # #python 会自动帮你转成 dog1.bulk(dog1)
依然没给self传值 ,但Python还是会自动的帮你把dog1 赋值给self这个参数, 为什么呢? 因为,你在bulk(..)方法中可能要访问dog1的一些其它属性呀, 比如这里就访问了dog1的名字,怎么访问呢?你得告诉这个方法呀,于是就把dog1传给了这个self参数,然后在bulk里调用 self.name 就相当于调用dog1.name
总结一下2点:
上面定义了类Dog,并创建了一个实例dog1,那么类变量和实例变量是什么区别和联系?
类变量没实例化就能打印,存在类的内存里。
先找实例本身,实例本身没有就去类里找
实例化只拷贝构造函数,不拷贝类变量和其他方法,那些还只在类的内存中。
所以类变量可以存放所有实例一些共同的属性,以节省空间。比如存放用户信息,用户姓名等属性可以放在实例变量里,国籍都是中国,可以放在类变量里。
但是,类变量和类方法方法不在实例中,调用怎么调用呢?
dog1.bulk() # 实际是 :Dog.bulk(dog1)
>>> dog1 = Dog('wangcai')
>>> dog1.bulk()
wangcai wang wang
>>> Dog.bulk(dog1)
wangcai wang wang
所以类里每个函数都必须至少有个self方法
dog1.age = 3 # 增加属性
del dog1.name # 删除属性
dog1.n = "111"
# 改类变量,实际不是改类变量,而是在实例里添加一个属性
Dog.n ="ccc" #改变类变量
析构函数:
跟构造函数相反
在实例释放、销毁的时候执行的,通常用于做一些收尾工作,如关闭一些数据库连接、打开的临时文件
如在上面的Dog类中添加一个析构函数
def __del__(self):
print("%s 挂了" %self.name)
类的私有属性和私有方法:
现在类的私有属性和私有方法,外边可以直接调用,比如Dog.n。如果不想被调用,在前面加两个下划线,就变成了私有属性或私有方法
前面提到:封装,就是使用构造方法将内容封装到某个具体对象中,然后通过对象直接或者self间接获取被封装的内容
封装是面向对象的特征之一,是对象和类概念的主要特性。
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
作用:省代码
面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
继承的过程,就是从一般到特殊的过程。
要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。
示例:
# class SchoolMember: 经典类写法
class SchoolMember(object): # 新式类
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def tell(self):
pass
def __del__(self):
'''析构方法'''
print("\033[31;1mmember [%s] left the school\033[0m" %self.name)
class Teacher(SchoolMember): # 继承父类SchoolMember
def __init__(self,name,age,sex,salary,course):
# 如何继承父类的构造函数?直接定义则重构了父类的构造函数
# 继承父类的构造函数,如下两种写法:
# SchoolMember.__init__(self,name,age,sex) # 经典类写法
super(Teacher,self).__init__(name,age,sex) # 新式类写法
self.salary = salary
self.course = course
def tell(self):
print('''
---- info of Teacher:%s ----
Name:%s
Age:%s
Sex:%s
Salary:%s
Course:%s
'''%(self.name,self.name,self.age,self.sex,self.salary,self.course))
def teach(self):
print("%s is teaching course [%s]" %(self.name,self.course))
class Student(SchoolMember):
def __init__(self,name,age,sex,stu_id,grade):
super(Student,self).__init__(name,age,sex)
self.stu_id = stu_id
self.grade = grade
def tell(self):
print('''
---- info of Student:%s ----
Name:%s
Age:%s
Sex:%s
Stu_id:%s
Grade:%s
''' % (self.name, self.name, self.age, self.sex, self.stu_id, self.grade))
def pay_tuition(self,amount):
print("%s has paid tution for $%s"% (self.name,amount) )
上面提到了经典类和新式类:
经典类写法:
class 类名: # 定义类
父类名.__init__(self,*args) # 继承父类构造函数
新式类写法:
class 类名(object): # 定义类
super(类名,self).__init__(name,*args) # 继承父类
经典类和新式类区别主要体现在多继承上顺序问题,现在规范写法用新式类
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
def __init__(self):
print("D")
obj = D()
A # 父类
/ \
/ \
B C # B类和C类继承A
\ /
\ /
D # D多继承B、C
继承查找策略:
广度优先:D->B->C->A(横向先都查完)
继承顺序从左到右,找到构造函数就停下来,注意方法只是定义在内存中
深度优先:D->B->A, D->C->A
python 3: 都是统一广度优先
python 2: 经典类是按深度优先继承,新式类是按广度优先继承的
深度没有广度效率高
多继承示例:
class People(object): # 新式类
def __init__(self,name,age):
self.name = name
self.age = age
self.friends = []
def eat(self):
print("%s is eating..." % self.name)
def talk(self):
print("%s is talking..." % self.name)
def sleep(self):
print("%s is sleeping..." % self.name)
class Relation(object):
# def __init__(self,n1,n2):
# print("init in relation")
def make_friends(self,obj): #w1
print("%s is making friends with %s" % (self.name,obj.name))
self.friends.append(obj.name)
class Man(Relation,People):
def __init__(self,name,age,money=10):
# People.__init__(self,name,age)
super(Man,self).__init__(name,age) # 新式类写法
self.money = money
print("%s 一出生就有%s $" %(self.name,self.money))
def sleep(self):
People.sleep(self)
print("man is sleeping ")
class Woman(People,Relation):
def get_birth(self):
print("%s is born a baby...." % self.name)
m1 = Man("XiaoMing",22)
w1 = Woman("XiaoHong",20)
m1.make_friends(w1)
class Teacher(SchoolMember):
def __init__(self,name,age,sex,sourse, school_obj):
super(Teacher,self).__init__(name,age,sex)
# SchoolMember.__init__(self,name,age,sex)
self.school = school_obj # 组合方式,“继承”
self.course = course
转载请务必保留此出处:http://blog.csdn.net/fgf00/article/details/52449707
一种接口,多种形态。
比如打印每类动物的叫声,每次都调用不同的类名,不仅麻烦,而且要记住不同的类名,因此:
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
pass #raise NotImplementedError("Subclass must implement abstract method")
@staticmethod
def animal_talk(obj):
obj.talk()
class Cat(Animal):
def talk(self):
print('%s Meow!'%self.name)
class Dog(Animal):
def talk(self):
print('%s Woof! Woof!'%self.name)
d = Dog("GreyHound")
#d.talk()
c = Cat("Ocelot")
#c.talk()
# def animal_talk(obj):
# obj.talk()
Animal.animal_talk(c)
Animal.animal_talk(d)
转载请务必保留此出处:http://blog.csdn.net/fgf00/article/details/52449707