创建对象的流程(可以称为这个类的一个实例)
p1 = Person()的运行流程
1.创建一个变量
2.在内存中创建一个新对象
3.__init__(self)方法执行
4.将对象的id赋值给变量
封装是面向对象的三大特性之一
# 封装指的是隐藏对象中一些不希望被外部所访问到的属性或方法
# 如何隐藏一个对象中的属性?
# - 将对象的属性名,修改为一个外部不知道的名字
# 如何获取(修改)对象中的属性?
# - 需要提供一个getter和setter方法使外部可以访问到属性
# - getter 获取对象中的指定属性(get_属性名)
# - setter 用来设置对象的指定属性(set_属性名)
# 使用封装,确实增加了类的定义的复杂程度,但是它也确保了数据的安全性
# 1.隐藏了属性名,使调用者无法随意的修改对象中的属性
# 2.增加了getter和setter方法,很好的控制的属性是否是只读的
# 如果希望属性是只读的,则可以直接去掉setter方法
# 如果希望属性不能被外部访问,则可以直接去掉getter方法
# 3.使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的
# 4.使用getter方法获取属性,使用setter方法设置属性
# 可以在读取属性和修改属性的同时做一些其他的处理
# 5.使用getter方法可以表示一些计算的属性
#保证数据的安全性,使用getter和setter方法
class Dog:
def __init__(self,name,age,gender,tail):#魔术方法
self._name = name
self._age = float(age)
self._gender = gender
self._tail = float(tail)
# property装饰器,用来将一个get方法,转换为对象的属性
# 添加为property装饰器以后,我们就可以像调用属性一样使用get方法
# 使用property装饰的方法,必须和属性名是一样的
@property
def get_name(self):
print('get方法执行了~~~')
return self._name
# setter方法的装饰器:@属性名.setter
@get_name.setter #这个地方为什么装饰器不起作用#set方法修饰的,必须是get方法修饰的函数否则
def set_name(self , name):
print('setter方法调用了')
self._name = name
def run(self):
print("名字叫%s,有%s岁,性别为%s,有%s高的狗正在奔跑"%(self.name,self.age,self.gender,self.tail))
def jiao(self):
print("性别为{},高{},有{}岁的{}正在叫!!!".format(self.gender,self.tail,self.age,self.name))
d=Dog("tom",15,"女","135")
d.set_name="xiaoming123"#调用了set_name这个方法,调用此方法时需要注意
print(d.set_name)
判断一个实例是否属于这个类可以用方法
R=isinstance(d,Dog)#isinstance这个方法判断d,是不是这个Dog的一个实例
print(R)
继承也是类的一大特性,创建类时默认后面是object,这个表示所有类的最大父类集。
# 如果在子类中如果有和父类同名的方法,则通过子类实例去调用方法时,
# 会调用子类的方法而不是父类的方法,这个特点我们成为叫做方法的重写(覆盖,override)
# 创建Dog类的实例
# d = Dog()
# d.run()
# 当我们调用一个对象的方法时,
# 会优先去当前对象中寻找是否具有该方法,如果有则直接调用
# 如果没有,则去当前对象的父类中寻找,如果父类中有则直接调用父类中的方法,
# 如果没有,则去父类的父类中寻找,以此类推,直到找到object,如果依然没有找到,则报错
class Person():
def __init__(self,name):
self._name = name
# property装饰器,用来将一个get方法,转换为对象的属性
# 添加为property装饰器以后,我们就可以像调用属性一样使用get方法
# 使用property装饰的方法,必须和属性名是一样的
@property
def name(self):
print('get方法执行了~~~')
return self._name
# setter方法的装饰器:@属性名.setter
@name.setter
def name(self , name):
print('setter方法调用了')
self._name = name
class Beijin_Person(Person):
def __init__(self,name,age):
super().__init__(name)
#Person.__init__(self,name)#直接调用父类,这时直接将父类写死,而且需要传递self产数进去
# super() 可以用来获取当前类的父类,
# 并且通过super()返回对象调用父类方法时,不需要传递self
self._age=age
@property
def age(self):
return self._age
@age.setter
def age(self, age):
self._age = age
P=Beijin_Person("TOM","13")
print(P.age)
print(P.name)
P.name="joke"
P.age=15
print(P.age)
print(P.name)
13
get方法执行了~~~
TOM
setter方法调用了
15
get方法执行了~~~
joke
进程已结束,退出代码为 0