Day14 Python课程学习内容

Day14 Python课程学习内容

1 封装

封装的引入

# ---------------------------------课堂案例---------------------------------
# 定义一个车的属性。
# 定义车的属性 name color 方法 run() laba()
class Car:
	def __init__(self,name,color):
		self.name = name
		self.color = color
	def run(self):
		print('The car starts to run')
	def laba(self):
		print('%s Didididi...'%self.name)
c = Car('Honda','black')
print(c.name,c.color) # Honda blak
c.run() # The car starts to run
c.laba() # Honda Didididi...
# ---------------------------------分割线---------------------------------
# 定义一个车的属性
# 属性 name color 方法 run() laba()
class Car:
	def __init__(self,name,color):
		self.name = name
		self.color = color
	def run(self):
		print('The car starts to run')
	def laba(self):
		print('%s Didididi...'%self.name)
c = Car('Honda','black')
c.name = 'Tokoy'
c.color = 'White'
print(c.name,c.color) # Tokoy White
# 目前我们客户可以直接通过,对象.属性 的方式来修改属性的值,把么这样子十分的不安全。
# ---------------------------------分割线---------------------------------
# 安全方式,需要一种方式,来增加数据的安全性。
# 1.属性不能随意修改。2属性不能随意修改成任何值。
# 所以开始用到封装。

  • 封装是面向对象的三大特性之一。
  • 封装是指隐藏对象中一些不希望被外界访问到的属性和方法。
# ---------------------------------课堂案例---------------------------------
class Dog:
	def __init__(self,name):
		self.name = name
dog1 = Dog('Erha')
dog1.name = 'Jinmao'
print(d.name)
# 为了保护对象中的属性,使用封装
# ---------------------------------分割线---------------------------------
# 如何隐藏属性?讲对象的属性名修改成外界不知道的名字。
class Dog:
	def __init__(self,name):
		self.hidden_name = name
	def speak(self):
		print('%s Wangwangwang!!'%self.hidden_name)
dog1 = Dog('Erha')
dog1.name = 'Jinmao'
dog1.speak() # Erha Wangwangwang!! 实现属性不会修改
dog1.hidden_name = 'Jinmao'
dog1.speak() # Jinmao Wangwangwang!! 实现属性会修改
# 封装并不是完全不能修改,只是为防止修改,而隐藏真实的名称。
  • 需要提供一个getter和setter方法是外部可以访问并修改属性。
# ---------------------------------课堂案例---------------------------------
class Dog:
	def __init__(self,name):
		self.hidden_name = name
	def speak(self):
		print('%s Wangwangwang!!'%self.hidden_name)
	def get_name(self):
		return self.hidden_name # 訪問
	def set_name(self):
		self.hidden_name = name # 修改
dog1 = Dog('Erha')
print(dog1.get_name()) # Erha
dog1.speak() # Erha Wangwangwang!!
dog1.set_name('Jinmao')
dog1.speak() # Jinmao Wangwangwang!!
# 封装并不是完全不能修改,只是为防止修改,而隐藏真实的名称。

类的封装,确实增加了类定义的复杂度,但是它也能确保数据的安全性。
1.隐藏了属性名,使调用在无法随意的修改对象的属性。
2.增加getter和setter方法,很好空值属性是否只读或修改
3.使用setter方法设置属性,可以增加数据的验证,确保数据的值是否正确
4.在读取和修改属性的时候可以做其他的处理

# ---------------------------------课堂案例---------------------------------
class Dog:
	def __init__(self,name,age):
		self.hidden_name = name
		self.hidden_age = age
	def get_age(self):
		return self.hidden_age
	def set_age(self,age):
		if age > 0:
			self.hidden_age = age # 修改
	def speak(self):
		print('%s Wangwangwang!!'%self.hidden_name)
	def get_name(self):
		return self.hidden_name # 訪問
	def set_name(self,name):
		self.hidden_name = name # 修改
dog1 = Dog('Erha', 5)
print(dog1.get_age()) # 5
dog1.set_age(8)
print(dog1.get_age()) # 8
dog1.set_age(-3)
print(dog1.get_age()) # 8
# 封装并不是完全不能修改,只是为防止修改,而隐藏真实的名称。

在这里插入图片描述


  • 封装的扩展
  • 可以对对象的属性使用双下划线的方式 __xxx来命名,一般一条下划线
# ---------------------------------课堂案例---------------------------------
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('Sam')
print(p.get_name()) # Sam
p.set_name = 'Janice'
print(p.get_name()) # Sam  没有修改
print(p.__name)
'''
   print(p.__name) 
AttributeError: 'Person' object has no attribute '_name'
'''

这种封装的方式其实是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('Sam')
print(p.get_name()) # Sam
p.set_name = 'Janice'
print(p.get_name()) # Sam  没有修改
p._Person__name = 'Janice'
print(p.get_name()) # Janice 属性修改

2. Property装饰器

@property 用来修饰方法的
作用:
1、@property 来创建只读属性,会将方法转换成相同名称的属性
2、可以防止属性被修改
# ---------------------------------课堂案例---------------------------------
# 创建一个基础类
class Person:
	def __init__(self,name):
		self._name = name
	def name(self):
		return self._name
p = Person('Sam')
print(p.name()) # Sam

# ------------------------------------------------------------------------
# 添加@property
class Person:
	def __init__(self,name):
		self._name = name
	@property
	def name(self):
		return self._name
p = Person('Sam')
print(p.name) # Sam 使用@property可以使调用方法后面不添加()
# ------------------------------------------------------------------------
# 修改属性
class Person:
	def __init__(self,name):
		self._name = name
	@property
	def name(self):
		return self._name
p = Person('Sam')
p.name = 'Janice'
print(p.name) 
'''
	p.name = 'Janice'
AttributeError: can't set attribute
'''
# ------------------------------------------------------------------------
# 如果要修改属性,setter方法的装饰器 @属性名.setter
class Person:
	def __init__(self,name):
		self._name = name
	@property
	def name(self):
		return self._name
	@name.setter
	def name(self,name):
		self._name = name
p = Person('Sam')
p.name = 'Janice'
print(p.name) # Janice

在这里插入图片描述


3. 继承

  • 继承更是面向对象的三大特性之一
    1.继承提高了代码的复用性
    2.让类与类之间产生了关系,有了这个关系,才有了后面的多态性

class Animal:
	def run(self):
		print('Run')
	def sleep(self):
		print('Sleep')
a = Animal()
a.run() # Run

# --------------------------------分割线--------------------------------
# 定义一个狗类,重新定义一个狗类
# 需要赋值粘粘比较麻烦
class Animal:
	def run(self):
		print('Run')
	def sleep(self):
		print('Sleep')
a = Animal()
a.run()
class Dog:
	def run(self):
		print('Run')
	def sleep(self):
		print('Sleep')
	def home('self')
		print('Home')

'''
1.直接修改动物类 修改起来麻烦,一会违反 ocp原则。
2.直接创建个狗类 创建了一个新类比较麻烦,同样需要大量的复制黏贴和修改
3.直接从Animal类中继承他的属性和方法
在定义类的时候,可以在类名的后面的括号中指定当前的父类(超类、基类)
在创建类的时候,如果省略了父类,则默认视父类为 object
object是所有类的父类,所有类继承于object

如果子类中有和父类同名的方法,则通过子类调用方法时,会调用子类的方法,而不是父类的方法,这个特点为方法的重写(覆盖,override)
'''
# --------------------------------分割线--------------------------------
# 所以用到父类继承
class Animal:
	def run(self):
		print('Run')
	def sleep(self):
		print('Sleep')
class Dog(Animal):	
	def home(self):
		print('Home')
d = Dog()
d.run() # Run
d.sleep() # Sleep
d.home() # Home
r = isinstance(d,Dog)
print(r) # True d是Dog的实例
r = isinstance(d,Animal)
print(r) # True d是Animal的实例,也是Dog的实例。
print(issubclass(Dog,Animal))  # True Dog是Animal的子类
print(issubclass(Animal,object))  # True Animal是object的子类
print(issubclass(Dog,object)) # True Dog是objct的子类
# issubclass() 检查一个类是不是另外一个类的子类
# --------------------------------分割线--------------------------------
# 修改子类,即方法的从写。
class Animal:
	def run(self):
		print('Run')
	def sleep(self):
		print('Sleep')
class Dog(Animal):	
	def home(self):
		print('Home')
	def run(self):
		print('Dog Run')
d = Dog()
d.run() # Dog Run
# Dog 内部的run方法覆盖父类Animal的run方法。
# ---------------------------------课堂案例---------------------------------
# Part 1
# 当A中有,而B、C中没有test的方法时,c会寻找父类B内的方法,而父类中没有想要的方法,就会继续找父类的父类A中的test方法,调用父类A中的方法
class A(object):
	def test(self):
		print('AA')
class B(A):
	pass
class C(B):
	pass
c = C()
c.test() # AA
# Part 2
# 当A,B中有,而C中没有test的方法时,c会寻找父类B内的方法,父类的父类A中的test方法,直接输出父类B当中的方法。
class A(object):
	def test(self):
		print('AA')
class B(A):
	def test(self):
		print('BB')
class C(B):
	pass
c = C()
c.test() # BB
# Part 3
# 当A,B,C中都有test的方法时,c会直接调用C内的方法,而不会去寻找父类B和父类的父类A中的test方法。
class A(object):
	def test(self):
		print('AA')
class B(A):
	def test(self):
		print('BB')
class C(B):
	def test(self):
		print('CC')
c = C()
c.test() # CC
# Part 4
# 当所有父类都没有方法时,则会返回报错信息。
class A(object):
	pass
class B(A):
	pass
class C(B):
	pass
c = C()
c.test() 
'''
    c.test()
AttributeError: 'C' object has no attribute 'test'
'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值