python类和对象入门_python基础-第七篇-7.1初识类和对象

创建类和对象

刚开始我们接触得多的编程方式为面向过程编程,这种方式就是根据业务逻辑从上往下垒代码,后来又出现了函数式编程,就是为了提高代码的重用性,减轻程序猿的工作量--而今天我们即将学的

面向对象编程则是使用类和对象来实现的,类就是一个模板,模板里可以包含多个函数,函数里实现一些功能

对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

942693-20160624163814875-1584539846.png

class是关键字,表示类

创建对象--类名称后加括号

#创建类

class foo:

def bar(self):

print('bar')

def hello(self,name):

print('i am %s'%name)

#根据类foo创建对象ohj

obj = foo()

obj.bar() #执行bar方法

obj.hello('alex') #执行hello函数

那你可能会想:这样做好像并不比函数编程简便??

面向对象--创建对象,通过对象执行方法,看得出在方法执行上有个权限,只有对象才有这个权限

函数编程:只用调用就可,可以说没有权限,无论谁叫都到

结论:函数式的应用场景,各个函数之间是独立且无共用的数据

面向对象三大特性

面向对象有三大神奇功能:封装,继承,多态

一、封装

封装--好理解,从字面意思理解,把什么玩意封在某个地方,好比:人的五脏六腑封装在人的体内样的,所以封装特性表现为:

将内容封装到某处

从某处调用被封装的内容

第一个表现--将内容封装到某处

942693-20160624171039813-1293459146.png

第二个表现:从某处调用被封装的内容

通过对象直接调用

通过self间接调用

942693-20160624175337891-1525546105.png

好,封装就是这样,封装了某些属性到对象,然后可以用对象直接调用,或self间接调用,简单吧

二、继承

继承--和生活中的继承是一样一样的,即:子可以继承父的技能

举个列子:

猫可以:喵喵叫、吃喝拉撒

狗可以:汪汪叫、吃喝拉撒

我们可以很明显的发现,狗和猫都会吃喝拉撒,不仅狗和猫会,是个动物都会,如果如要分别写这个两个类,吃喝拉撒是不是就要写两遍了,那继承的特性就是为了在这方面方便我们的

class animal:

def eat(self):

print('%s吃'%self.name)

def drink(self):

print('%s喝'%self.name)

def shit(self):

print('%s拉'%self.name)

def pee(self):

print('%s撒'%self.name)

#在类后面括号中写入另外一个类名,表示当前类继承另外一个类

class cat(animal):

def __init__(self,name):

self.name = name

self.breed = '猫'

def cry(self):

print('喵喵叫')

class dog(animal):

def __init__(self,name):

self.name = name

self.breed = '狗'

def cry(self):

print('汪汪叫')

c1 = cat('小白家的小黑猫')

c1.eat()

d1 = dog('胖子家的小瘦狗')

d1.drink()

所以,对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法,另外除了父类和子类的称谓,还可以叫基类和派生类

942693-20160624203911281-1624911266.png

那疑问又来了,是否可以继承多个类?如果遇到继承的多个类中都定义了相同的函数,那么会执行哪个呢?

1、Python的类可以继承多个类,Java和C#中则只能继承一个类

2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先

272315068126604.jpg

当类是经典类时,多继承情况下,会按照深度优先方式查找

当类是新式类时,多继承情况下,会按照广度优先方式查找

经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。

272341313127410.jpg

272341553282314.jpg

#多继承

#经典类

class classmate():

def __init__(self,name):

self.name = name

def eat(self):

print('%s is eating.'%self.name)

def drink(self):

print('%s is drinking.'%self.name)

#派生类1:

class female(classmate):

def drink(self):

print('%s drink orange juice'%self.name)

#派生类2:

class male(classmate):

def drink(self):

print('%s is drink alcohol'%self.name)

class pythoner(classmate):

def occuption(self):

print('%s is a pythoner.'%self.name)

class fe_pythoner(pythoner,female):

pass

class ma_pythoner(pythoner,male):

pass

eva = fe_pythoner('eva')

eva.drink()

sweet = ma_pythoner('sweet')

sweet.drink()

#新生类

class classmate(object):

def __init__(self,name):

self.name = name

def eat(self):

print('%s is eating.'%self.name)

def drink(self):

print('%s is drinking.'%self.name)

class female(classmate):

def drink(self):

print('%s drink orange juice.'%self.name)

class male(classmate):

def drink(self):

print('%s drink alcohol.'%self.name)

class pythoner(classmate):

def occupation(self):

print('%s is a pythoner.'%self.name)

class fe_pythoner(pythoner,female):

pass

class ma_pythoner(pythoner,male):

pass

eva = fe_pythoner('eva')

eva.drink()

sweet = ma_pythoner('sweet')

sweet.drink()

#结论:在python3中,类的继承默认就是广度优先

# 在python2中,经典类多继承,按照深度优先查找,新式类多继承按广度优先查找

另外子类继承父类的构造方法:

class fund(object):

def __init__(self,fund_type,fund_name):

self.fund_type = fund_type

self.fund_name = fund_name

def chao(self):

pass

class index_fund(fund):

def __init__(self,fund_type,fund_name,nav):

super(index_fund,self).__init__(fund_type,fund_name)

self.nav = nav

def cao(self):

pass

def prin(self):

print('{} is {},now jingzhi is {}'.format(self.fund_name,self.fund_type,self.nav))

obj1 = index_fund('指数型基金','富国中证500',2.2)

obj1.prin()

三、多态

Pyhon不支持多态并且也用不到多态,多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。

class F1:

pass

class S1(F1):

def show(self):

print 'S1.show'

class S2(F1):

def show(self):

print 'S2.show'

# 由于在Java或C#中定义函数参数时,必须指定参数的类型

# 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类

# 而实际传入的参数是:S1对象和S2对象

def Func(F1 obj):

"""Func函数需要接收一个F1类型或者F1子类的类型"""

print obj.show()

s1_obj = S1()

Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show

s2_obj = S2()

Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show

class F1:

pass

class S1(F1):

def show(self):

print 'S1.show'

class S2(F1):

def show(self):

print 'S2.show'

def Func(obj):

print obj.show()

s1_obj = S1()

Func(s1_obj)

s2_obj = S2()

Func(s2_obj)

类和对象在内存中的存储原理

类以及类中的方法在内存中只有一份,而根据类创建的每一个对象都在内存中需要存一份

425762-20150829133530437-321533636.jpg

如上图所示,根据类创建对象时,对象中除了封装 name 和 age 的值之外,还会保存一个类对象指针,该值指向当前对象的类。

当通过 obj1 执行 【方法一】 时,过程如下:

根据当前对象中的 类对象指针 找到类中的方法

将对象 obj1 当作参数传给 方法的第一个参数 self

欢迎大家对我的博客内容提出质疑和提问!谢谢

笔者:拍省先生

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值