面向对象基础:封装、继承、多态
print("--------------------封装----------------------")
'''
封装:将变量封装到类里,通过实例对象直接、间接调用。
'''
# 定义一个类
# ()内为所继承的类
class Student(object):
weight = None # 此时默认为None,这个变量归类所有,可以通过类调用Student.weight
#__init__相当于构造器,生成实例对象,__开头__结尾的是特殊变量,但不是私有变量
# self表示某个类实例对象,调用时自动传入
def __init__(self,name,age,score):
#这里的变量是绑定的是实例变量,不能类直接调用,生成对象实例后才有的变量
self.__name = name #__开头的为私有变量,外部不能直接访问
self.__age = age #虽然外面没有定义__age,但该语句也相当于定义一个__age,只能对象通过实例调用
self.score = score
# 私有变量可以通过外部可访问的函数间接调用
def getName(self):
return self.__name
def setName(self,name):
self.__name = name
def msg(self):
print("这是一个学生")
def msg2(self):
print("还在读书")
# 生成实例
stu1 = Student('fw',22,88)
print(stu1.getName())
stu1.hight = 180 #给stu1对象绑定一个属性变量并赋值,Student类里是没有hight的
stu2 = Student('f',1,90)
print(stu2.weight)
# stu1.hight将会报错
# 给实例绑定属性
stu2.stu2var = 1
print(stu2.stu2var) # 1
# 类直接调用类属性,
print(Student.weight) # None
# 覆盖类属性
stu2.weight = 56
print(stu2.stu2var) # 1
print(Student.weight) #None
# print(Student.name) #name是实例变量,AttributeError: type object 'Student' has no attribute 'name'
print("--------------------继承----------------------")
'''
继承:子类继承父类,拥有父类属性和方法,可重写父类方法
'''
class Freshman(Student):
# 重写msg
def msg(self):
print("这是一个大一学生")
fresh1 = Freshman('fwz',22,90)
fresh1.msg() #执行重写后的msg
fresh1.msg2() # 执行父类的msg2
#可以看到,fresh1既是Freshman又是父类Student
print(isinstance(fresh1,Student))
print(isinstance(fresh1,Freshman))
# 子类有父类的东西,但父类不一定有子类的东西,所以
print(isinstance(stu1,Freshman))
print("--------------------多态----------------------")
'''
多态:根据传入的不同的参数类型执行不同功能的
'''
def printMsg(m):
m.msg()
printMsg(stu1)
printMsg(fresh1)
'''
--------------------封装----------------------
fw
None
1
None
1
None
--------------------继承----------------------
这是一个大一学生
还在读书
True
True
False
--------------------多态----------------------
这是一个学生
这是一个大一学生
'''
绑定实例的方法method类型和普通函数function类型区别
'''绑定实例的方法method和普通函数function区别'''
class A():
def g(self):
print("有self参数的g()")
def h():
print("没有self参数的h()")
pass
s = A()
# 定义一个函数,想要将self对象中age的值设为传入参数age
def set_age(self, age):
self.age = age
from types import MethodType
s.set_age1 = MethodType(set_age, s)
print('type s.set_age1:',type(s.set_age1))
s.set_age1(10)
print(s.age)
'''
method,此时set_age绑定到实例set_age1变量上,作为该实例一个方法
此时当调用s.set_age1(10),self参数自动指向s
'''
s.set_age2 = set_age
print('type s.set_age2:',type(s.set_age2))
s.set_age2(s,10)
print(s.age)
'''
function,此时set_age2被赋值为set_age函数对象,只是一个普通函数,self需要手动传入
s.set_age2(s,10)
'''
# A.g() 报错 TypeError: g() missing 1 required positional argument: 'self'
a = A()
print('type A.g:',type(A.g))# function 所以类.g是普通函数
A.h()
print('type A.h:',type(A.h))# function 所以类.h是普通函数
A.g(a)# 因为是正常函数,self参数不会自动指向,需要自己传入a实例
print('type a.g:',type(a.g))# method a.g是实例对象的方法,调用时self自动指向a
a.g()
print('type a.h:',type(a.h))# method h()是class内定义的
# a.h() #抛出异常TypeError: h() takes 0 positional arguments but 1 was given,因为是类内定义的,a.h()会自动传入一个self,与h()定义时参数数量不符
'''
输出:
type s.set_age1: <class 'method'>
10
type s.set_age2: <class 'function'>
10
type A.g: <class 'function'>
没有self参数的h()
type A.h: <class 'function'>
有self参数的g()
type a.g: <class 'method'>
有self参数的g()
type a.h: <class 'method'>
'''
多继承实现额外动作或拥有额外属性
'''
支持多继承,实现特定方法,满足额外的动作需求
'''
class Student(object):
# self参数要写,实例对象自动把自己传进去,self接收
def learning(self):
print("ta在上学...")
pass
class Worker(object):
def working(self):
print("牛马在打工...")
# 一个大一学生类,他还可能出去兼职,具有打工相关的方法
class Freshman(Student,Worker):
pass
f = Freshman()
f.learning()
f.working()
参考
函数的参数 - Python教程 - 廖雪峰的官方网站 (liaoxuefeng.com)