一 类与对象的理解与封装特性
1.面向对象的三大特性:
1、封装 :根据职责将属性和方法封装到一个抽象的类内
2、继承 :主要是为了实现代码的重用,相同的代码不需要重复的编写
3、多态 :不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
可如下划分:
- 类: 一个模板, (人类)—是一个抽象的, 没有实体的
- 对象: (eg: 张三,李四)
- 属性: (表示这类东西的特征, 眼睛, 嘴巴, 鼻子)
- 方法:(表示这类物体可以做的事情, eg: 吃饭, 睡觉,学习)
#1.定义类:class
class 人类(object):
#object代表人类继承于哪一个类,如果不知道就写object
#构造魔术方法,当创建对象的时候,会自动执行的函数
def __init__(self,name,age,gender):
#python解释器自动将对象传给self这个形参,看self是什么
#将对象与对象的属性绑在一起
self.name=name #属性
self.age=age
self.gender=gender
print(self)#实质上是一个对象:<__main__.人类 object at 0x7fed39b4f668>
#方法(在类里面定义的函数,叫做方法)
def eat(self):
print('%s正在吃饭...' %(self.name))
#创建对象-->根据模板(类)创建对象(真实存在)
person=人类('张三',10,'male')
print('张三:',person)
#看对象的属性
print(person.name)
print(person.age)
print(person.gender)
#让对象执行方法
person.eat()
二 类的私有属性和私有方法
类的私有属性:
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。
在类内部的方法中使用时 self.__private_attrs
类的方法:
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,
类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的(因为是形参),也可以使用 this,但是最好还是约定self。
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用,不能在类地外部调用。self.__private_methods
三.数据封装
栈的数据结构
栈的方法:
入栈(push), 出栈(pop), 栈顶元素(top),栈的长度(lenght), 判断栈是否为空(isempty),显示栈元素(view)
操作结果:
栈类的实例化
入栈2次
出栈1次
显示最终栈元素
class Stack(object):
#构造函数
def __init__(self):
self.stack=[]
def push(self,value):
"""
:param value: 入栈元素
:return:
"""
self.stack.append(value)
return True
def pop(self):
#判断栈是否为空
if self.stack:
#获取栈元素,并返回
item=self.stack.pop()
return item
else:
return False
def top(self):
if self.stack:
return self.stack[-1]
else:
return False
def length(self):
return len(self.stack)
def isempty(self):
return self.stack==[]
def view(self):
return ','.join(self.stack)
s=Stack()
s.push('1')
s.push('3')
s.push('2')
s.push('5')
#item=s.pop() #栈元素来说,后进先出
print(s.top())
print(s.length())
print(s.isempty())
队列数据结构
队列的方法:
入队(enqueue), 出队(dequeue), 队顶元素(top),队的长度(length), 判断队是否为空(isempty),显示对元素(view)
操作结果:
队列类的实例化
入队5次
出队1次
显示最终对列元素
class Queue(object):
def __init__(self):
self.queue=[]
def enqueue(self,value):
return self.queue.append(value)
def dequeue(self):
if self.queue:
return self.queue.remove(self.queue[0])
else:
return False
def top(self):
if self.queue:
return self.queue[0]
else:
return False
def length(self):
return len(self.queue)
def view(self):
return ','.join(self.queue)
q=Queue()
q.enqueue('2')
q.enqueue('3')
q.enqueue('6')
q.enqueue('5')
q.enqueue('4')
#q.dequeue() #先进先出
print(q.view())
print(q.length())
print(q.top())
四.继承
父类与子类/基类和派生类
定义一个 class 的时候,可以从某个现有的 class 继承,新的class 称为子类、派生类,而被继承的 class 称为基类,父类。
如下我定义一个Animal类
如果我接着建立一个子类的话,就可以直接继承其属性和方法
class Tiger(Animal):
pass
class Bird(Animal):
pass
Tiger与Bird为Animal的子类,Animal为其父类,将所有属性,方法传递给Tiger,Bird.
注意:
1.如果子类没有的属性和方法, 则去父类找, 如果父类也没有, 就报错
2.父类的私有属性, 子类的方法时不能查看与操作
五 多继承原理
# 经典类
class Person1:
pass
p1 = Person1()
print(p1)
# 新式类
class Person2(object):
pass
p2 = Person2()
print(p2)
新式类方法与属性继承时 子类使用广度优先算法
经典类方法与属性继承时,子类使用深度优先算法
Python3中全部使用新式类
class D:
def test(self):
print('D test')
class C(D):
pass
def test(self):
print('C test')
class B(D):
pass
# def test(self):
# print('B test')
class A(B,C):
pass
# def test(self):
# print('A test')
a=A()
a.test()
六 多态
在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行。