面向对象微讲解(三)
面向对象微讲解(三)
面向对象三大特征之封装
-
封装的含义
封装就是将类中的某些名字'隐藏'起来,不想让外界直接调用,但是呢又提供了专门的通道去访问,可以在通道内添加额外
的功能。这个通道呢就是我们经常说的接口,将数据隐藏起来就限制了类外部对数据的直接操作,类外部想要操作数据就需要使用类
内提供的相应的接口来间接的操作数据,接口之上我们就可以添加额外的逻辑来限制数据的操作。
那怎么才是封装呢,或者说怎么封装名字呢?
在类中想要封装一个名字,只需要在该名字的前面加上两个下划线,但是注意一下只有在类的定义阶段封装的功能才能生效。虽
然我们是封装了起来,但是并不是绝对的,只是改变了语法,给它做了一个变形,并不是我们看上去的那样。
-
封装的简单操作
# class Student:
# # 对school数据进行了封装
# __school = '复旦大学'
# def Teacher(self):
# pass
# obj = Student()
# print(obj.__school) # 运行发现报错了,报错说类中没有__school这个数据,可是我们写了的,这就是封装,不能直接操作
数据
# 我们刚刚已经讲过封装只是改变了语法,给它做了一个变形
# print(Student.__dict__) # _Student__school 我们封装的名字变成了这样
# print(obj._Student__school) # 复旦大学 我们直接使用这个是可以的
# 我们是不能直接这样使用这个名字,因为我们封装起来就是为了外部不能直接操作数据的
class Student:
# 对school数据进行了封装
__school = '复旦大学'
def __init__(self,name,age):
self.__name = name
self.__age = age
# 设置一个专门访问数据的通道或者说接口
def check_name(self):
print(self.__name)
# 设置一个专门访问数据的通道或者说接口
def check_age(self):
print(self.__age)
# 设置一个专门访问数据的通道或者说接口,还可以做一些额外的操作
def check_info(self):
print('名字:%s 年龄:%s'% (self.__name,self.__age))
def check(self):
if self.__name == 'oscar':
print('%s大人你好'%self.__name)
if self.__age == 21:
print('生日快乐')
obj = Student('oscar',21)
obj.check_name() # oscar
obj.check_age() # 21
obj.check_info() # 名字:oscar 年龄:21
obj.check() # oscar大人你好 生日快乐
-
伪装(property)
property伪装就是将方法伪装成数据,有时候很多数据都是经过计算获得,这些数据的计算应该数据而不是功能,比如
BMI指数,应该属于人的数据而不是人的功能。
class Person():
def __init__(self,name,height,weighe):
self.__name = name
self.__height = height
self.__weight = weighe
@property
def BMI(self):
print('%s的BMI指数为%s'% (self.__name,self.__weight / self.__height ** 2))
obj = Person('oscar', 1.78,80)
# obj.BMI()
'''
发现会有一个报错信息说不具备调用括号的能力,可是我们写的就是一个方法
方应该是具备调用括号的能力的,因为我们加了一个语法糖@property,进行了伪装
把方法伪装成了数据,调用数据的时候是不需要加括号的
'''
obj.BMI # oscar的BMI指数为25.24933720489837
面向对象三大特性之多态
-
多态的含义
多态就是一种事物的多种形态,比如说水就有固态、液态、气态,这三种形态可以统称为水,比如说动物,猫是动
物、狗是动物、鸡是动物,这是动物的多种形态。
多态呢是一种编程思想,偏向于理论。我们来举个例子:人可以分为白种人、黑种人、黄种人,他们都有说话的能力,不
可能就因为肤色不一样就不能说话了,我们定义一个Person类,类里面有一个speak方法,然后我们再来定义三个子类来继承
Person类,这三个子类分别是White_person、Black_person、Yellow_person类,每一个子类都有自己关于说话的方法,
但是各不相同,这样我们来用的时候就有点麻烦,所以呢我们就可以利用多态的思想,每个子类的的关于说话的方法其本质就
是关于说话的不同的表现形式,那我们把所有关于说话的方法都定义为同一个名字,这样的好处就在于增强了程序的灵活性和
可扩展性。
多态性是有一个鸭子类型理论的:只要看着像鸭子、走路像鸭子、说话像鸭子,那么就是鸭子。
-
多态简单演示
class Person:
def speak(self):
pass
class White_person(Person):
def speak(self):
print('白种人说话的方法')
class Black_person(Person):
def speak(self):
print('黑种人说话的方法')
class Yellow_person(Person):
def speak(self):
print('黄种人说话的方法')
bai = White_person()
hei = Black_person()
huang = Yellow_person()
bai.speak() # 白种人说话的方法
hei.speak() # 黑种人说话的方法
huang.speak() # 黄种人说话的方法
-
强制实现多态
import abc
# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Person(metaclass=abc.ABCMeta):
@abc.abstractmethod # 该装饰器限制继承它的子类必须有一个名为speak的方法
def speak(self): # 抽象方法中无需实现具体的功能
pass
class White_person(Person): # 继承了Person类的子类内部必须有名为speak的方法,没有就会报错
def speak(self):
print('白种人说话的方法')
class Black_person(Person): # 继承了Person类的子类内部必须有名为speak的方法,没有就会报错
def speak(self):
print('黑种人说话的方法')
class Yellow_person(Person): # 继承了Person类的子类内部必须有名为speak的方法,没有就会报错
def talk(self):
print('黄种人说话的方法')
bai = White_person()
hei = Black_person()
huang = Yellow_person()
bai.speak()
hei.speak()
huang.speak()
面向对象之反射
反射的含义
反射是指程序可以访问、检测和修改本身状态或者行为的一种能力,其实就是通过字符串来操作对象的数据和功能
的能力。
-
反射的四个方法
hasattr():判断对象是否含有字符串对应的功能或者数据
getattr():根据字符串获取对应的变量名或者函数名
setattr():根据字符串给对象设置键值对(名称空间中的名字)
delattr():根据字符串删除对象对应的键值对(名称空间中的名字)
-
反射的简单演示
class Student1:
school = '复旦大学'
student_id = 123
def choose(self):
pass
obj = Student1()
print(hasattr(obj,'school')) # 含有就返回True
print(hasattr(obj,'teacher')) # 不含有就返回False
print(getattr(obj,'school')) # 复旦大学 含有就返回对应的值
print(hasattr(obj,'teacher')) # 不含有就返回False
setattr(obj,'student_class','python12') # 不含有就创建
setattr(obj,'student_id','python12') # 含有就修改
print(obj.student_class) # python12
print(obj.student_id) # python12
delattr(obj,'student_class')
print(hasattr(obj,'student_class')) # False
这里是IT小白陆禄绯,欢迎各位大佬的指点!!!
