类和对象的成员分析
类和对象都可以储存成员, 成员可以归类所有,也可以归对象所有
类存储成员时使用的是与类关联的一个对象
独享存储成员是存储在当前的对象中
class A():
name = "xiaowang"
age = 16
def say(self):
self.name = "shaiz"
self.age = 18
print(A.name)
print(A.age)
print(id(A.name))
print(id(A.age))
a = A()
print(a.name)print(a.age)
print(id(a.name)) # 对比id
print(id(a.age))
a.name = "xiaoshabi"
a.age = 19
print(a.name)
print(a.age)
print(id(a.name)) # 对比id
print(id(a.age))
self
self在对象的方法中表示当前对象本身,如果通过对象调用一个方法,那么该对象会自动传入到当前
self不是关键字,理论上可以用任何一个普通变量
class A():
name = "xiaowang"
age = 16
def say(self):
self.name = "小哥哥"
self.age = 18
print("My name is {0}".format(self.name))
print("My age is {0}".format(self.age))
def ask(): # 没有self
print("Tell me why ")
a = A()
a.say()
A.ask() # 要用绑定类名
封装
封装就是对对象进行访问权限限制
三个级别:
公开:public
受保护的:protected
私有的:private
私有
私有是最高级别的封装,只能在当前类或者对象中访问
封装方法:在成员前面添加两个下划线,表示成员私有
Python中的私有,并不是真正意义上的私有,只是自动把变量名改了,可以通过__dict__来查看
1 class Person():
2 name = "小哥哥" # 公有
3 __age = 20 # 私有
4
5 p = Person()
6 print(p.name) # 访问公有
7 # print(p.age) # 访问私有///报错
8 print(Person.__dict__) # 查看
受保护的封装
将对象成员就像一定级别的封装,然后,在类中或者子类中都可以进行访问,但是在外部不可以
封装方法:在成员前面加一个下划线
公有
对成员不进行任何操作即可,任何地方都可以访问
继承
继承就是一个类可以获得另外一个类中的成员属性和成员方法
用来减少代码,增加代码的复用
所有的类都继承object类,因此所有类都是object类的子类
1 class Person(object): # 继承objetc类
2 name = "laoshi"
3 age = 16
4 def sleep(self):
5 print("我睡了。。。。。")
6
7 class Teacher(Person): # 继承Person
8 def make_test(self):
9 print("考试考试考试")
10 a = Teacher()
11 print(a.name) # Teacherl类继承了person类
12 print(Teacher.name) # Teacherl类继承了person类
子类和父类定义同一个变量名称,则优先使用子类本身
1 class person(object):
2 name = "我是Person"
3 class Teacher(Person):
4 name = "我是teacher"
5
6 t = Teacher()
7 print(t.name)
子类如果想扩充父类的方法,可以在定义新方法的同事访问父类成员进行代码重用
1 class Person(object):
2 name = "我是Person"
3 age = 19
4 def work(self):
5 print("make some money")
6 class Teache(Person):
7 name = "我是teacher"
8 def make_tset(self):
9 print("attention")
10 def work(self):
11 Person.work(self) # 扩充父类功能只需要调用父类相应的函数
12 #super().work() # 扩充的第二种方法
13 self.make_tset()
14
15 x = Teache()
16 x.work()
继承变量函数的查找顺序
优先查找自己的变量,没有则查找父类
构造函数如果本类中没有定义,则自动查找调用父类构造函数
如果有,则不继续向上查找
构造函数
是一类特殊的函数
__init__()函数,每次实例化的时候第一个被自动调用
主要工作是进行初始化
1 class sport():
2 def __init__(self): # __这就是构造函数
3 print("一起做运动!")
4 # 实例化,自动调用__init__
5 me = sport()
super
首先super不是关键字,它是一个类
作用是获取MRO列表中的第一个父类
super与父类没有任何实质性的关系,但super可以调用到父类
单继承和多继承
单继承:每个类只能继承一个类
优点:
继承有序,逻辑清晰,语法简单
缺点:
功能不能无限拓展,只能在唯一的一条继承链中拓展
多继承:每个类允许继承多个类
优点:
类的功能拓展方便
缺点:
继承关系混乱,隐患多,产生菱形问题
1 class Fish(object):
2 def __init__(self, name):
3 self.name = name
4
5 def swim(self):
6 print("swiming.......")
7
8
9 class Bird(object):
10 def __init__(self, name):
11 self.name = name
12
13 def fly(self):
14 print("flying.......")
15
16
17 class Person(object):
18 def __init__(self, name):
19 self.name = name
20
21 def work(self):
22 print("working.......")
23
24
25 class Student(Person): # 单继承
26 def __init__(self, name):
27 self.name = name
28 stu = Student("Bud")
29 stu.work()
30
31 class SuperMan(Person, Bird, Fish): # 多继承
32 pass
33 s = SuperMan("Burtit")
34 s.fly()
35 s.swim()
多态
多态就是同一个对象在不同情况下有不同的状态出现
多态不是语法,是一种思想
多态性:一种调用方式,不同的执行效果
多态:同一种事物的多种形态,如动物分为人类,鸡类,毛类
类相关函数
issubclass(): 检测一个类是不是另一个类的子类
isinstance(): 检测一个对象是否是一个类的实例
hasatter: 检测一个对象是否有某个成员
getattr: 获取属性值,必须存在
setattr:设置属性值,属性必须存在
delattr:删除属性
dir(): 获取对象的成员列表
and so on...
1 class A():
2 age = 16
3 class B(A):
4 pass
5 class C():
6 pass
7
8 print(issubclass(B, A)) # 检测B是否是A的子类
9 a = A()
10 print(isinstance(a, A)) # 检测a是否为A的实例
11 print(getattr(a,"age")) # 查看a中的age的值
12
13 print(setattr(a, 'age', 199)) # 将a中的age值改为199
14 print(a.age)
15 print(delattr(A, 'age')) # 删除A中age的值
16 print(A.__dict__) # 查看发现无age了
17 print(hasattr(a,'age')) # 检测a中是否有成员age
dir(A) # 获取a的成员列表