Python基础第13讲 - 面向对象(2)
一、 面向对象 - 特殊方法(魔术方法)
特殊方法都是以__开头__结尾的方法
特殊方法不需要自己调用
学习特殊方法
1、特殊方法什么时候调用
2、特殊方法有什么作用
对于Person这个类name属性是必须,并且每一个实例对象的name属性是不一样的
我们现在是将name属性手动添加
特别容易出错
对象的创建流程
p1 = Person
1、创建一个变量
2、在内存中创建了一个新的对象
3、执行类中的代码中的代码(只在类中执行一次)
4、__init__方法执行了
'''
案例 1
'''
class Person:
name = '葫芦娃'
def speak(self):
print('大家好,我是%s'%self.name)
p1 = Person()
p2 = Person()
p1.speak()
p2.speak()
'''
优化 1
'''
class Person:
def speak(self):
print('大家好,我是%s'%self.name)
p1 = Person()
p1.name = '葫芦娃'
p2 = Person()
p2.name = '钢铁侠'
p2.speak()
p3 = Person()
p3.name = '洛萨'
p3.speak()
'''
优化 2
'''
class Person:
print('Person类中的代码')
def __init__(self):
self.name = '葫芦'
def speak(self):
print('大家好,我是%s'%self.name)
p1 = Person()
p2 = Person()
p3 = Person()
p4 = Person()
p1.speak()
结果: Person类中的代码
大家好,我是葫芦
'''
优化 3
'''
class Person:
print('Person类中的代码')
def __init__(self,name):
self.name = name
def speak(self):
print('大家好,我是%s'%self.name)
p1 = Person('狐狸卡')
print(p1.name)
p2 = Person('钢铁侠')
print(p2.name)
p1.speak()
p2.speak()
结果: Person类中的代码
狐狸卡
钢铁侠
大家好,我是狐狸卡
大家好,我是钢铁侠
类的基本结构
class 类名([父类])
公共属性...
对象的初始化方法
__init__(self, .... )
.....
其他的方法
def method(self,...):
...
二、类的练习
属性:name color
方法:run() laba()
class Car():
def __init__(self,name,color):
self.name = name
self.color = color
def run(self):
print('车开始跑了')
def laba(self):
print('%s 嘀嘀'%self.name)
c = Car('宝马','蓝色')
c.name = '奥迪'
c.color = '绿了'
print(c.name,c.color)
c.run()
c.laba()
结果: 奥迪 绿了
车开始跑了
奥迪 嘀嘀
我们要增加数据安全性
1、属性不能修改(我让你改才能,不让改就不能改)
2、属性不能改为任意的值
三、面向对象 - 封装(可选择性修改)
3.1 封装是面向对象的三大特性之一(封装、继承、多态)
3.2 封装指的是隐藏对象中一些不希望被外部访问到的属性或方法
'''
没封装的
'''
class Dog:
def __init__(self,name):
self.name = name
d = Dog('二哈')
d.name = '凯撒'
print(d.name)
结果: 凯撒
如何隐藏对象中的一个属性
将对象的属性名,修改为一个外部不知道的名字
如何获取(修改)对象当中的属性
我们可以提供一个getter和setter方法可以访问和修改
使用封装,确实增长了类的定义复杂度,但是确保了安全性
1、隐藏了属性名,是调用者无法随意修改对象当中的属性
2、增加了getter和setter方法,可以很好的控制属性是否只读的
如果希望属性是只读的,则可以直接去掉setter方法
如果希望属性不能被外界访问,则可以 直接去掉getter方法
3、使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的
4、可以在读取属性和设置属性做一些操作
'''
封装后的
1、get_name名称可以成别的,但是return那句不能学错
'''
class Dog:
def __init__(self,name,age):
self.hidden_name = name
self.hidden_age = age
def speak(self):
print('大家好,我是%s'%self.hidden_name)
def get_age(self):
return self.hidden_age
def set_age(self,age):
if age > 0:
self.hidden_age = age
def get_name(self):
return self.hidden_name
def set_name(self,name):
self.hidden_name = name
d = Dog('二哈',12)
d.set_age(-20)
d.speak()
d.set_name('凯撒')
d.speak()
print(d.get_name(),d.get_age())
四
可以为对象的属性使用双下划线开头(__xxx)
双下划线开头的属性是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过外部访问
隐藏属性是python自动为属性改了一个名字
实际改的名字是:_类名_属性名 __name -> _Person__name
一般情况,使用一个下划线(_)开头的属性都是私有属,没有特殊情况不要修改私有属性
class Person:
def __init__(self,name):
self._name = name
def get_name(self):
return self._name
def set_name(self,name):
self._name = name
p = Person('葫芦娃')
p._Person__name = '黑猫警长'
p.__name = '黑猫警长'
print(p.get_name())
五 @property 装饰器
用来将一个get方法 转换为对象的属性
添加property装饰器以后,我们就可以像的调用属性一个调用方法
class Person:
def __init__(self,name):
self._name = name
@property
def name(self):
print('get方法执行了')
return self._name
@name.setter
def name(self,name):
self._name = name
p = Person('HY')
p.name= '滚个'
print(p.name)
结果: get方法执行了
滚个