对象和类
类(class):是现实或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起
对象(object):是具有类型的变量,类和对象是面向对象编程技术中的基本的概念
类是创建实例的摸版
对象是一个一个具体的实例
例如:
运行:
封装特性
面向对象的三大特性是指:封装,继承和多态
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容
所以在使用面向对象封装特性时,需要:
1:将内容封装到某处
2:通过对象调用被封装的内容
通过对象调用被封装的内容:对象.属性名
通过self间接调用被封装的内容:self.属性名
通过self讲解调用被封装的内容:self.方法名
封装特性对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容
练习
创建一个类People拥有的属性为姓名,性别和年龄,拥有的方法为购物,玩游戏,学习,实例化对象,执行相应的方法,显示如下:
小明,18岁,男,去西安赛格购物广场购物
小王,22岁,男,去西安赛格购物广场购物
小红,10岁,女,在西部开源学习
1
class people:
def _ _init_ _(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def eating(self):
print('%s,%s岁,%s去西安赛格购物广场购物' %(self.name,self.age,self.sex))
def learing(self):
print('%s,%s岁,%s去西安赛格购物广场购物' %(self.name,self.age,self.sex))
def shoppinh(self):
print('%s,%s岁,%s在西部开源学习'%(self.name,self.age,self.sex))
p1 = people('小明',18,'男')
p1.eating()
p2 = people('小王',22,'男')
p2.learing()
p3 = people('小红',10,'女')
p3.shoppinh()
执行结果:
继承特性
继承描述的是事物之间的所属关系,当我们定义一个类的时候,可以从某个现有的类继承,新的类称为子类,扩展类,被继承的类称为父类,基类
问题1
如何实现继承?
子类在继承的时候,在定义类时小括号中为父类的名字
问题2
继承的工作机制是什么?
父类的属性,方法会被继承给子类。
重写父类方法
在子类中,如果有一个和父类相同的方法,就会覆盖父类的方法
实例:
class Student(object):
def __init__(self,name,age):
print('这是父类的构造方法...')
self.name = name
self.age = age
def learning(self):
print('正在执行父类的learning方法....')
print('学生%s正在学习....' %(self.name))
print(self.age)
class MathStudent(Student):
def learning(self):
print('正在执行子类的learning方法...')
print('数学系学生%s正在学习' %(self.name))
print(self.age)
m = MathStudent('杨进',19)
print('学生姓名:', m.name)
print('学生年龄:', m.age)
m.learning()
运行结果:
私有属性和私有方法
默认轻快下属性在Python中都是“public”,大多数OO语言提供“访问控制符”来限定成员函数的访问
在Python中,实例的变量名如果以__开头就变成了一个私有变量/属性。实例的函数名如果以__开头就变成了一个私有函数/方法,只有内部可以访问,外部不能访问
私有属性和私有方法的优势
确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮
如果又要允许外部代码修改属性怎么办?
可以给类增加专门设置属性方法。
多态特性
多态,按字面意思来说就是多种状态,在面向对象语言中,接口的多种不同的实现方式即为多态,通俗来说:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果
多态的优势
多态的好处就是当我们需要传入更多的子类,只要继承父类就可以了,而方法也可以直接不重写,也可以重写一个特有的这就是多态的意思,调用方只管调用不管细节,而当我们新增一种子类时,只要确保方法编写正确而不用管原来的代码,这就是著名的开闭原则:
对扩展开放:允许子类重写方法函数
对修改封闭:不重写,直接继承父类方法函数
栈与队列的封装
栈
栈是限制在一端进行插入操作和删除操作的线性表俗称堆栈,允许进行操作的一端称为栈顶,另一端称为栈底,当栈中没有元素时称为空栈,向栈中插入元素称为进栈,删除栈中元素称为出栈,栈的特点:后进先出
练习
栈的封装
class stack(object):
def __init__(self):
self.stack = []
def push(self,value):
self.stack.append(value)
print('元素%s入栈成功' %(value))
def pop(self):
if not self.is_empty():
a = self.stack.pop(-1)
print('%s出栈成功'%(a))
else:
raise Exception('栈为空')
def top(self):
if not self.is_empty():
return self.stack[-1]
else:
raise Exception('栈为空,不能获取栈顶元素')
def is_empty(self):
return len(self.stack) == 0
def __len__(self):
return len(self.stack)
def list(self):
print(self.stack)
if __name__ == '__main__':
s = stack()
s.push(5)
s.push(3)
print(len(s))
s.pop()
print(s.is_empty())
s.list()
运行结果:
队列
队列是限制在一端进行插入操作和另一端删除操作的线性表,允许插入操作的一端称为队尾,允许删除的一端称为队头当队列中没有元素时称为空对,队列特点:后进后出
练习
队列的封装
class List(object):
def __init__(self):
self.list = []
def enqueue(self,value):
self.list.append(value)
print('%s成功进入队列' %(value))
def dequeue(self):
if not self.is_empty():
b = self.list.pop(0)
print('%s元素删除成功' %(b))
else:
raise Exception('队列为空')
def is_empty(self):
return len(self.list) == 0
def first(self):
if not self.is_empty():
print(self.list[0])
else:
raise Exception('队列为空,无法获取第一个元素')
def num(self):
print(len(self.list))
def ls(self):
print(self.list)
if __name__ == '__main__':
l = List()
l.enqueue(5)
l.enqueue(3)
print(l.is_empty())
l.first()
l.num()
l.dequeue()
l.ls()
练习
二分搜索算法
二分查找又称折半查找,
优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。
因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
def binary_search(alist, item):
n = len(alist)
start = 0
end = n - 1
while start <= end:
mid = (start + end) // 2
if alist[mid] == item:
return True
elif item < alist[mid]:
end = mid - 1
else:
start = mid + 1
return False
if __name__ == '__main__':
li = [1,2,3,4,5]
print(binary_search(li, 1))
print(binary_search(li, 20))
运行结果: