类(class)是对现实或者思维世界中的实体在计算机中的反应,它将数据以及这些数据上的操作封装在一起。
对象(object)是具体有类类型的变量,类与对象是面向过程编程中最基本的概念。
注释:类与对象就是狗和哈士奇的区别,也就是酒与葡萄酒的区别,房子的设计图纸和真实房子的区别。
类就相当于一个模板,可以实例化出许多对象。对象类有属性,有方法。
类的定义:class 类():pass
类转化为对象:
实例化是指在面向对象编程过程中,把用类创建的对象的过程称为实例化。是将一个抽象的概念类,具体到该类的实物过程中。实例化过程中一般由类名 对象名= 类名(参数1,参数2,参数N)构成。
类(class)是创建实例的模板。
对象(object)是一个一个实例。
将内容封装到某个地方,以后再去调用被封装在该处的内容。所以,在使用面向对象的封装特性时,需要:
(1)将内容封装到某处。
(2)从某处调用被封装的内容。
(1)通过对象直接调用被封装的内容: 对象.属性名
(2)通过self间接调用被封装的内容:self.属性名
(3)通过self 间接调用被封装的内容:self.方法名()
构造方法__init__与其他普通方法不同的地方在于,当一个对象被创建后,会立即调用构造方法。自动执行构造方法里面的内容。
对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。
创建一个类People,拥有的属性为姓名, 性别和年龄, 拥有的方法为购物,玩游戏,学习;实例化对象,执行相应的方法。 显示如下:
小明,18岁,男,去赛格购物
小王,22岁,男,去玩游戏
小红,20岁,女,去学习
提示:
属性:name,age,gender
方法:shopping(), playGame(), learning()
程序
class Foo:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def shopping(self):
print("%s,%s岁,%s,去赛格购物" % (self.name, self.age, self.gender))
def playGame(self):
print("%s,%s岁,%s,去玩游戏" % (self.name, self.age, self.gender))
def learning(self):
print("%s,%s岁,%s,去学习" % (self.name, self.age, self.gender))
xiaoming = Foo('小明', 18, '男')
xiaoming.shopping()
laoli = Foo('老李', 22, '男')
laoli.playGame()
xiaohong = Foo('小红', 20, '女')
xiaohong.learning()
继承可分为:
(1)继承
(2)多继承
(3)私有属性和私有方法
在现实生活中,继承一般指的是子女继承父辈的财产,如下图:
是事物之间的所属关系,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类、扩展类(subclass),而被继承的class称为基类、父类或者超类(Baseclass、superclass)
问题一: 如何实现继承?
子类在继承的时候,在定义类时,小括号()中为父类的名字
问题二: 继承的工作机制是什么?
父类的属性、方法会被继承给子类,举例:如果子类没有__init__方法,父类有,那么在子类继承父类的时候这个方法就会被继承,如果只是创建对象,就默认执行了那个继承过来的__init__方法。
重写父类的方法:就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖父类的同名方法。
调用父类的方法:
1.父类名.父类的方法名()
2.super():py2.2+的功能
class People:
goal = "先挣它1个亿"
# 如果类里面的方法以双下划线开头/结尾, 魔术方法;
def __init__(self, name, age, money):
# 封装
self.name = name
self.age = age
self.money = money
def eat(self):
print("%s正在吃大餐" %(self.name))
# Son: 子类/扩展类
# 代表Son类的父类为Father;
class Son(People):
# Son没有构造方法, 因为父类Father有, 自动调用父类的构造方法;
goal = "先挣它10个亿"
def eat(self):
# 调用父类的方法(建议): 获取Son对应的父类,, 并执行该父类的eat方法
super(Son, self).eat()
print("%s正在吃xxxxxx" %(self.name))
# 实例化的过程: 通过类创建对象的过程
# wjl = Father("王健林", 68, 1000000000000)
wsc = Son("王思聪", 35, 10000000000)
wsc.eat()
print(wsc.goal)
多继承:即子类有多个父类,并且具有他们的特性:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190615122148435.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTExMzUwOA==,size_16,color_FFFFFF,t_70)
新式类:Python3中直接或者间接继承object的类,默认继承object类,Python3中所有的类都是新式类
经典类:Python2中没有直接或者间接继承object的类
二者的区别在于继承的搜索顺序不同:
新式类: 广度优先
经典类: 深度优先
默认情况下,属性在Python 中都有“public”,大多数oo 语言提供“访问控制符”来限定成员函数的访问。属性()
在python 中,实例的变量名如果以__开头,就会变成一个私有变量/属性(private)实例的函数名如果以 —开头,就变成了一个私有函数/方法(private)只有内部可以访问,外部不能访问。
问题:私有属性一定不能从外部进行访问么?
python2版本不能直接访问_属性名是因为python解释器对外把属性名改为了类名——属性名。所以任然可以通过 -类名-属性名来访问-属性名。
问题:为什么要有属性名和私有方法?
1.确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
2.如果又允许外部代码修改属性怎么办?可以给类增加设置属性方法。因为在方法中,可以对参数做检查,避免传入无效参数。
多态按照字面的意思就是多种状态。在面向对象语言中,借口的多种不同的实现方式即为多态。通俗的来说:同一种操作作用与不同的对象,可以有不同的解释,产生不同的执行效果。
多态的好处:当我们需要传入更多的子类,只需要继承父类就可以了,而方法既可以直接不重写(即使用父类的)也可以重写一个特有的。这就是多态的意思。调用方只管调用不管细节。而当我们新增加一种子类时,只要确保新方法编写正确。而不管原来的代码。这就是著名的“开闭”原则:
对扩展开放:允许子类重写方法函数。
对修改封闭: 不重写,直接继承父类的方法函数。
栈是限制在一端进行插入互操作和删除操作的线性表(俗称堆栈),允许进行的操作的一端为“栈顶”,另一端为“栈底”。当栈中没有元素时称为“空栈”。向一个栈类插入元素称为进栈,push;从一个栈中删除元素称为出栈,pop。特性:先进后出。
队列是限制在一端进行插入操作和另一端删除操作的线性表允许进行插入操作的一端为“队尾”。允许进行删除操作的一端称为“队头”,当队列中没有元素时称为“空队”。特点:先进先出
实现以下功能:
class Queue(object):
def __init__(self):
self.__queue=[]
def __len__(self):#求队列长度
return len(self.__queue)
def is_empty(self):
"""判断队列是否为空 """
return len(self.__queue) == 0
def enqueue(self,item):
"""入队操作"""
self.__queue.append(item)
print("元素[%s]入队成功" % (item))
def first(self):
"""求队头"""
if not self.is_empty():
item = self.__queue[0]
print('队头元素为:%s'%(item))
else:
raise Exception('队列为空')
def dequeue(self):
"""出队"""
if not self.is_empty():
item = self.__queue.pop(0)
print('元素%s出队成功'%(item))
else:
raise Exception('队列为空')
def Display_queue(self):
return self.__queue
Q = Queue()
Q.enqueue(5)
Q.enqueue(3)
print('队列内容为:',Q.Display_queue())
print('队长为:',len(Q))
Q.dequeue()
Q.is_empty()
Q.dequeue()
Q.is_empty()
# Q.dequeue()
Q.enqueue(7)
Q.enqueue(9)
Q.Display_queue()
Q.first()
Q.enqueue(4)
print('队长为:',len(Q))
Q.dequeue()
print('队列内容为:',Q.Display_queue())