小糖果python基础之面向对象(下)

1. 封装

1.1 封装的引入

  • (1) 定义封装(Encapsulation)
    对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其含义是其他程序无法调用。
      封装,就是将类或者是函数中的某些属性限制在某个区域之内,外部无法调用。
  • (2)为什么使用分装
    未封装属性 可以直接“对象.属性”来修改属性的值,这样导致不安全。
    因此,需要一种方式来增强数据的安全性即属性不能随意修改;属性不能修改成任意的值。Python通过封装的方式来解决该问题。

1.2 封装的方法

  • (1)封装是面向对象的三大特性之一。
    指隐藏对象中一些不希望被外界所访问到的属性和方法。

  • (2)如何隐藏属性
    将属性名修改成为外界不知道的名字。
    将属性名修改为hidden_name

class dog:
	def __init__(self,name):
		self.hidden_name = name#隐藏属性name
	def speak(self):
		print('大家好,我是%s'%self.hidden_name)
d=dog('二哈')
d.speak()
大家好,我是二哈

上述案例如果外界直接使用实例化对象名.属性名修改属性,不能直接修改属性。

d.name='哈哈哈'
#不能修改上述案例中的属性。
  • (3)隐藏属性的获取方法和修改方法
    需要提供一个gettersetter方法,这两个方法是外部可以访问并修改的。
    ----- (1)
#getter语法
def getter_name(self):
	#getter_name()这个方法用来获取对象的name属性
	return self.hidden_name

案例-getter

class dog:
	def __init__(self,name):
		self.hidden_name = name#隐藏属性name
	def speak(self):
		print('大家好,我是%s'%self.hidden_name)
	def get_name(self):
		return self.hidden_name
d=dog('二哈')
print(d.get_name())
二哈

#setter 语法
get_name(self,name)
	self.hidden_name=name

案例-setter

class dog:
	def __init__(self,name):#初始化的init的时候,不要在————末尾加name
		self.hidden_name=name
	def speak(self):
		print('大家好,我是%s'%self.hidden_name)
	#修改属性
	def set_name(self,name):#设置属性的时候需要在括号里面加name
		self.hidden_name=name#等于name
	def get_name(self):
		return self.hidden_name
d= dog('二哈')
d.speak()
d.set_name('大狼狗')
d.speak()
大家好我是二哈
大家好我是大狼狗
  • 封装说明:
    使用封装,会增加类的定义的复杂度,但是它也确保了数据的安全性。
    即:
    (1)隐藏了属性,在调用时无法随意修改对象的属性。
    (2)增加了gettersetter方法,较好的控制属性是否只读或修改。
    (3)使用setter的方法修改属性,增加数据的验证,确保数据值是正确的。例如可以在setter里面增加条件判断,满足条件的才会被修改,不满足条件的不能修改。
    (4)可以在读取和修改属性的时候做一些其他的处理。
    getter方法后面的括号里面没有name参数。

setter方法后面的括号里面有name参数。

1.3 封装方法的补充

可以对对象的属性使用双下划线的方式__xxx封装,
这种封装方式是python自动给属性起名字,外界不知道他的具体名字。
\一般情况下,用一个下划线就可以达到封装的目的_xxx
这个名字的样式是__类名__属性名例如__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

2. 拓展

2.1 @property

  • (1)@property是Python内置的@property装饰器就是负责把一个方法变成属性调用的。
  • (2)可以防止属性被修改。
class person:
	def __init__(self,name):
		self._name = name
	@property
	def name(self):
		print('get方法执行了')
		return self._name
p=person('葫芦娃')
print(p.name)
  • (2)@属性名.setter
    可以修改属性。
    具体参考:
    https://www.liaoxuefeng.com/wiki/897692888725344/923030547069856

3. 类的继承

继承是面向对象的三大特征之一。
作用:
继承提高了代码的复用性;
让类与类之间产生了关系,有了关系之后才有了后面的多态特性;

  • (1)类的继承语法:
    在定义子类的时候,可以在类名后的括号中指定当前的父类(超类,基类)。
class Animals:
	def run(self):
		print('动物会跑')
	def sleep(self):
		print('动物会叫')
class dog(Animals):#dog类继承了Animals类的,将Animals放于dog类的括号中
	def see_home(self):
		print('狗看家')
d=dog()
d.see_home()
d.run()
d.sleep()
狗看家
动物会跑
动物会叫
  • (2)在创建类的时候,如果省略了父类,则默认父类是object。object是所有类的父类。

  • (3)检查一个对象是否另一个类的实例。
    使用isinstance()函数检查

class Animals:
	def run(self):
		print('动物会跑')
	def sleep(self):
		print('动物会叫')
class dog(Animals):
	def see_home(self):
		print('狗看家')
r=isinstance(d,Animals)#检查一个对象是否另一个类的实例
print(r)
True
  • (4)检查一个类是否是另一个类的子类
    使用issubclass()函数
class Animals:
	def run(self):
		print('动物会跑')
	def sleep(self):
		print('动物会叫')
class dog(Animals):
	def see_home(self):
		print('狗看家')
r1=issubclass(dog,Animals)#检查一个类是否是另一个类的子类
print(r1)
True
  • (5)子类方法的添加和父类方法的重写

如果子类的方法与父类的方法重名时,则通过子类调用方法时,会调用子类的方法,而不是父类的方法,这个特点称为方法的重写(或者覆盖)。如果父类中的方法子类不够用,则可以在子类中添加新的方法。

注意:
当我们调用一个对象的方法时:
会优先去当前对象中寻找是否具有该方法,如果有则直接调用;
如果没有,则去当前对象的父类中寻找,如果父类中有则直接调用父类中的方法;
如果没有,则去父类中的父类寻找,以此类推,直到找到object,如果依然没有找到就报错了。

3.1 多重继承

多重继承就是一个儿子(子类)有多个爹(父类)。

调用函数__bases__可以获取当前类的所有父类,使用语法:子类名.__bases__

class Animals:
	def run(self):
		print('动物会跑')
	def sleep(self):
		print('动物会叫')
class dog(Animals):
	def see_home(self):
		print('狗看家')
print(dog.__bases__)#获取dog类的所有父类
(<class '__main__.Animals'>,)#dog的父类是Animals,该结果是个元组,所有可以有多个父类

注意:
如果多个父类中有同名的方法,则会优先在第一个父类中寻找,然后在第二个中找,依次类推。即前面的会把后面的覆盖。

4. 多态

多态也是面向对象的三大特征之一。
即 一个对象可以有多个不同的形态呈现。

  • 多态案例
class A:
    def __init__(self,name):
        self._name = name
    @property#getter方法装饰器
    def name(self):
        return self._name
    @name.setter#setter方法装饰器
    def name(self,name):
        self._name = name

class B:
    def __init__(self,name):
        self._name = name
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self,name):
        self._name = name
class C:
    pass
a = A('光辉')
a2 = A('Sam')
b = B('晓雯')
c = C()
def speak(o):
    print('你好,我是%s'%o.name)
speak(a)
speak(a2)
speak(b)
speak(c)
你好,我是光辉
你好,我是Sam
你好,我是晓雯
AttributeError: 'C' object has no attribute 'name'#对speak()这个函数,只要对象中有name属性,他就可以作为参数传递,该函数不会考虑对象的类型,只要有这个现象就是一个多态的体现
  • 非多态案例
    在speak2()中,我们做了一个判断,即只有o满足是A类型的对象时,才可以正常调用,而其他类型的对象没办法使用该函数,这个函数就违反了多态。
class A:
    def __init__(self,name):
        self._name = name
    @property#getter方法装饰器
    def name(self):
        return self._name
    @name.setter#setter方法装饰器
    def name(self,name):
        self._name = name

class B:
    def __init__(self,name):
        self._name = name
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self,name):
        self._name = name
class C:
    pass
a = A('光辉')
a2 = A('Sam')
b = B('晓雯')
c = C()
def speak2(o):
#判断
	if isinstance(o,A):
		print('你好,我是%s'%o.name)
speak2(a2)
你好,我是Sam

5. 总结面向对象的三大特性

  • 封装:确保数据的安全
  • 继承:保证了对象的扩展性
  • 多态 :保证了程序的灵活性

6. 属性和方法

6.1 类属性和实例属性

  • (1)类属性
    直接在类中定义的属性就是类属性;

类属性的特点:类属性可以通过类和类的实例访问
类属性只能通过类对象去修改,无法通过实例对象去修改。

  • (2) 实例属性
    通过实例对象添加的属性称之为实例属性。
    实例属性的特点:实例属性只能通过实例对象来访问,无法通过类对象访问。
class B:
	count=0#类属性
	def __init__(self):#实例属性,self为谁调用我就是谁,若a实例对象调用则为a.name=name#该形式为实例对象添加属性。
		self.name=name
a=B()

6.2 类方法 和 实例方法

  • (1) 实例方法

实例方法是在类中直接定义的;
在类中直接定义的,以self为第一个参数的都是实例方法。

当通过实例对象去调用方法时,会将当前对象作为self传入;
当通过类调用实例方法时,不会自动传递self,需要手动传入实例对象。

  • (2) 类方法
    定义类方法的时候需要使用@classmethod装饰器。
    类方法的第一个参数是cls,它也会自动传递,cls就是当前的类对象。

特点:类方法可以通过类对象和类的实例对象访问

@classmethod
def test2(cls):#括号中自动传入cls
	print('我是test2方法,我是一个类方法'

6.3 类的静态方法

使用装饰器@staticmethod.
静态方法基本是和当前类无关的方法,只是保存在当前类的一个函数;一般是一些工具方法,与当前类无关。

@staticmethod
def test3():#括号中没有参数
	print('我是test3,我是静态方法')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值