立习习学Python——第八天

面向对象编程

方法没有重载

在其他语言中,可以定义多个重名的方法,只要保证方法签名唯一即可。方法签名包含3个部分:方法名、参数数量和参数类型。而在Python中是没有方法重载的。

如果在类体中定义了多个重名的方法,只有最后一个方法有效。

方法的动态性

Python是动态语言,可以动态的为类添加新的方法,或者动态的修改类的已有的方法。

私有属性和私有方法(实现封装)

Python对于类的成员没有严格的访问控制限制,这与其他面向对象语言有区别。
关于私有属性和私有方法,有如下要点:

  • 通常约定,两个下划线开头的属性(方法)是私有的,其他是公共的。
  • 类内部可以访问私有属性(方法)。
  • 类外部不能直接访问私有属性(方法)。
  • 类外部可以通过"_类名 __私有属性(方法)名”访问私有属性。
class Employee:
	def __init__(self,name,age)
		self.name = name
		self.__age = age # 私有属性

me = Employee("wyx",19)

print(e.name)
print(e._Employee__age)

@property装饰器

@property 可以将一个方法的调用变成属性调用

class Employee:
	def __init__(self,name,salary):
		self.__name = name
		self.__salary = salary
	
	@property
	def salary(self):
		return self.__salary

	@salary.setter
	def salary(self,salary):
		if 1000<salary<50000:
			self.__salary = salary
		else:
			print("录入错误!薪水在1000-50000这个范围")	

emp1 = Employee("wyx",20000)
print(emp1.salary)
emp1.salary = 20000
print(emp1.salary)
class Employee:
	def __init__(self,name,salary):
		self.__name = name
		self.__salary = salary
	
	def get_salary(self):
		return self.__salary = salary
	
	def set_salary(self,salary):
		if 1000<salary<500000:
			self.__salary = salary
		else:
			print("录入错误!薪水在1000-50000这个范围")

emp1 = Employee("wyx",20000)
print(emp1,get_salary())
emp1.set_salary(30000)
print(emp1.get_salary())

上面两个代码的作用是一样的,但是使用@property装饰器的代码在调用的使用更为简单。

面向对象三大特征介绍

Python是面向对象的语言,也支持面向对象编程的三大特性:继承,封装(隐藏)、多态。

  1. 封装(隐藏):隐藏对象的属性和实现细节,只对外提供必要的方法。相当于将“细节封装起来”,只对外暴露“相关调用方法”。
  2. 继承:继承可以让子类具有父类的特性,提高了代码的重用性。从设计上是一种增量进化,原有父类设计不变的情况下,可以增加新的功能,或者改进已有的算法。
  3. 多态:多态是指同一个方法调用由于对象不同会产生不同的行为。生活中这样的例子比比皆是:同样是休息,人不同休息方法不同。张三休息是睡觉,李四休息是玩游戏,程序员休息是敲几行代码。

继承

继承是面向对象程序设计的重要特征,也是实现代码复用的重要手段。
如果一个新类继承自一个设计好的类,就直接具备了已有类的特征,就大大降低了工作难度。已有的类,我们称之为“父类或者基类”,新的类,我们称为“子类或者派生类”。

语法格式

Python支持多重继承,一个子类可以继承多个父类。继承的语法格式如下:

class 子类类名(父类1[,父类2,]):
	类体

如果在类定义中没有指定父类,则默认父类是object类。也就是说,objetc是所有类的父类,里面定义了一些所有类共有的默认实现。

class Person:
	def __init__(self,name,age)
		self.name = name
		self.age = age
		
	def say_age(self):
		print("年龄")

class Student(Person):
	def __init__(self,name,age,score):
		Person.__init__(self,name,age)
		self.score = score
s = Student()
s.say_age()
类成员的继承和重写
  1. 成员继承:子类继承了父类除构造方法之外的所有成员。
  2. 方法重写:子类可以重新定义父类中的方法,这样就会覆盖父类的方法,也称为“重写”。
# 测试方法重写
class Person:
	def __init__(self,name,age):
		self.name = name
		self.__age = age
	
	def say_age(self):
		print("我的年龄:",self.__age)
	
	def say_introduce(self):
		print("我的名字是{0}".foramt(self.name))
class Student(Person):
	
	def __init__(self,name,age,score):
		Person.__init__(self,name,age)
		self.score = score

	def say_introduce(self):
		print("报告老师,我的名字是:{0}".format(self.name))

s = Student("wyx",19,100)
s.say_age()
s.say_introduce # 子类重写了父类的方法,在调用时,会调用子类的方法
查看类的继承层次结构

通过类的方法mro()或者类的属性“mro”可以输出这个类的继承层次结构。

Object根类

object类是所有类的父类,因此所有的类都有object的属性。

注:

  • 内置函数dir()可以方便的看到指定对象所有的属性。
  • 方法也是一种特殊的属性。
重写__str__()方法
class Person:
	def __init__(self,name)
		self.name = name
	def __str__(str):
		return"名字是:{0}".format(self.name)
p = Person("wyx")
多重继承

Python支持多重继承,一个子类可以有多个“直接父类”。这样,就具备了“多个父类”的特点。但是会搞得异常复杂,尽量避免使用。

super()获得父类定义

在子类中,如果想要获得父类的方法时,我们可以通过super()来做。super()代表父类的定义,不是父类对象。

# 测试super()
class A:
	def say(self):
		print("A:",self)

class B(A):
	def say(self):
		A.say(self)
		print("B:",self)
B().say()
class A:
	def say(self):
		print("A:",self)

class B:
	def say(self):
	super().say()
	print("B:",self)

多态

多态是指同一个方法调用由于对象不同可能会产生不同的行为。
注意:

  1. 多态是方法的多态,属性没有多态
  2. 多态的存在有两个必要条件:继承方法重写
class Man:
	def eat(self):
		print("饿了,吃饭啦!")

class Chinese (Man):
	def eat(self):
		print("中国人用筷子吃饭")

class English(Man):
	def eat(self):
		print("英国人用叉子吃饭")

class Indian(Man):
	def eat(self):
		print("印度人用右手吃饭")

def manEat(m):
	if isinstance(m,Man):
		m.eat()
	else:
		print("不能吃饭")	
特殊方法和运算重载符

Python的运算符实际上是通过调用对象的特殊方法实现的。
每个运算符实际上都对应了相应的方法,统计如下:

运算符特殊方法说明
运算符+_add_加法
运算符-_sub_减法
<,<=,==_lt_, _le_, _eq_比较运算符
>, >=,!=_gt_, _ge_, _ne_比较运算符
|, ^, &_or_, _xor_, __and异、异或、与
<<, >>_lshift_, _rshift_左移、右移
*,/, %, //_mul_, _truediv_, _mod_, _floorfiv_
**pow指数运算
在这里插入代码片

常用的特殊方法统计如下:

方法说明例子
_init_构造方法对象创建:p = Person()
_del_析构方法对象回收
_repr_, _str_打印,转换print(a)
_call_函数调用a()
_getattr_点号运算a.xxx
_setattr_属性赋值a.xxx = value
_getitem_索引运算a[key]
_setitem_索引赋值a[key] = value
_len_长度len(a)
class Person:
	def __init__(self,name)
		self.name = name
	def __add__(self,other) # 完成运算符的重载
		if isinstance(other,Person):
			return"{0}--{1}".format(self.name,other.name)
		else:
			return"不是同类对象,不能相加"

p1 = Person("wyx")
p2 = Person("xjj")
特殊属性
特殊方法含义
obj.__dict__对象的属性字典
obj.__class__对象所属的类
class.__bases__类的基类元组(多继承)
class.__base__类的基类
class.__mro__类层次结构
class.__subclasses__()子类列表

对象的浅拷贝和深拷贝

  • 变量的赋值操作:只是形成两个变量,实际还是指向同一个对象。
  • 浅拷贝:Python拷贝一般都是浅拷贝。拷贝时,对象包含的子对象内容不拷贝。
  • 深拷贝:使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象。源对象和拷贝对象所有的子对象也不同。
import copy
class MobilePhone:
	def __init__(self,cpu,screen)
		self.cpu = cpu
		self.screen = screen

class CPU:
	def calculate(self):
		print("计算")
		print("cpu对象:",self)

class Screen:
	def show(self):
		print("显示一个好看的画面")
		print("screen对象:",self)

c1 = CPU()
c2 = c1
print(c1)
print(c2)

s1 = Screen()
m1 = MobilePhone(c1,s1)
m2 = copy.copy(m1) # 浅复制

print(m1,m1.cpu,m1.screen)
print(m2,m2.cpu,m2.screen) # 只有第一个地址不一样

m3 = copy.deepcopy(m1) # 深复制
print(m1,m1.cpu,m1.screen)
print(m3,m3.cpu,m3.screen)# 均不一样

组合

"is-a"关系,可以用“继承”。从而实现子类拥有的父类的方法和属性。
“has-a”关系,可以用“组合”,也能实现一个类拥有另一个类的方法和属性。

class A1:
	def say_a1(self):
		print("a1,a1,a1")

class B1(A1):
	pass
	
b1 = B1()
b1.say_a1()

class A2:
	def say_a2(self):
		print("a2a2a2")

class B2:
	def __init__(self,a):
		self.a = a

a2 = A2()
b2 = B2(a2)
b2.a.say_a2()

设计模式

设计模式是面向对象语言特有的内容,是我们在面临某一类问题时候固定的做法。

工厂模式实现

工厂模式实现了创建者和调用者的分离,使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制。

class CarFactory:
	def creat_car(self,brand):
		if brand =="奔驰"return Benz()
		elif brand == "宝马"
			return BMW()
		elif brand == "比亚迪"
			return BYD()
		else:
			return"未知品牌,无法创建"

class Benz:
	pass

class BMW:
	pass

class BYD:
	pass
factory = CarFactory()
c1 = factory.creat_car("奔驰")

单例模式实现

单例模式的核心作用是确保一个类只有一个实例,并且提供一个访问该实例的全局访问点。
单例模式只生成一个实例对象,减少了对系统资源的开销。当一个对象的产生需要比较多的资源,如读取文件、产生其他依赖对象时,可以产生一个“单例对象”,然后永久驻留内存中,从而极大地降低开销。

class MySingleton:
	__obj = None #类属性
	__init_flag = True
	def __new__(cls,*args,**kwargs):
		if cls.__obj ==None:
			cls.__obj = object.__new__(cls)
		return cls.__obj

	def __init__(self,name):
		if MySingleton.__init_flag:
			print("init……")
			self.name = name
			MySingleton.__init_flag = False

a = MySingleton("aa")
b = MySingleton("bb")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值