Python编程学习-基础笔记07
九、面向对象编程
9.1 私有化
'''
私有化:
封装: 1,私有化属性;2,定义共有的set和get方法
__属性 : 就是将属性私有化,将访问范围控制在类中
优点:
1,隐藏属性,不被外界随意修改
2,可以通过函数set来修改
def setXXX(self,xxx)
3,筛选赋值内容,加if判断
4,如果想获取具体的某一属性,使用get函数
def getXXX(self)
'''
class Student:
def __init__(self,name,age):
self.__name = name
self.__age = age
self.__score = 59
#定义共有的set和get方法
#set 是赋值
def setAge(self,age):
if age > 0 and age < 100:
self.__age = age
else:
print('年龄不在规定的范围')
def setName(self,name):
if len(name)==6:
self.__name = name
else:
print('姓名不是6位!')
#get 是取值
def getAge(self):
return self.__age
def __str__(self):
return f'姓名:{self.__name},年龄:{self.__age},分数:{self.__score}'
jack = Student('Jack',19)
print(jack)
jack.setAge(100) # 超出范围,年龄不在规定的范围
print(jack) #姓名:Jack,年龄:19,分数:59 依然打印原始值
print(jack.getAge())
9.2 @property装饰器
'''
在开发中常看到的一些私有化处理:装饰器
'''
class Student:
def __init__(self,name,age):
self.name = name
self.__age = age
#旧版
# #set 是赋值
# def setAge(self,age):
# if age > 0 and age < 100:
# self.__age = age
# else:
# print('年龄不在规定的范围')
# #get 是取值
# def getAge(self):
# return self.__age
#新版,加装饰器,先有getxxx
@property
def age(self):
return self.__age
#必须首先定义age函数,再定义setXXX
@age.setter
def age(self,age):
if age > 0 and age < 100:
self.__age = age
else:
print('年龄不在规定的范围')
def __str__(self):
return f'姓名:{self.name},年龄:{self.__age}'
s = Student('Jack',19)
print(s)
#name 没有私有化
s.name = 'Luise'
print(s)
# #旧版:私有化赋值
# s.setAge(30)
# print(s.getAge())
#新版加装饰器的赋值
s.age = 100
print(s.age)
9.3 关联关系
'''
关联: has a; 继承: is a
练习要求:
公路 Road
属性:公路名称,公路长度
车 Car
属性:车名,时速
方法:
1,求车在哪条公路上以多少时速行驶了多长距离
get_time(self,road)
2,初始化车属性信息 __init__方法
3,打印对象,现实车的属性信息
'''
import random
#定义road 类
class Road:
def __init__(self,name,length):
self.name = name
self.length = length
def __str__(self):
return f'公路名:{self.name},长度:{self.length}'
#定义car类
class Car:
def __init__(self,brand,speed):
self.brand = brand
self.speed = speed
def get_time(self,road): # road = r ,他们指向同一地址
ran_time = random.randint(1,10)
msg = f'{self.brand}的车在{road.name}高速上以{self.speed}km/h行驶了{ran_time}小时'
return msg
def __str__(self):
return f'品牌:{self.brand},速度:{self.speed}'
#创建实例对象
r = Road('S51',500)
print(r) #公路名:S51,长度:500
audi = Car('Audi',120)
print(audi) #品牌:Audi,速度:120
print(audi.get_time(r)) #Audi的车在S51高速上以120km/h行驶了3小时
r.name = 'S35'
print(audi.get_time(r)) #Audi的车在S35高速上以120km/h行驶了5小时
对象也是一种数据类型。
'''
关联: has a
1,has a
一个类中使用了另一个自定义的类型
student 使用了computer 和 book
2,类型:
系统类型: str,list,dict .....
自定义类型:算是自定义的类,都可以当成一种类型
s = Student()
s是Student类型的对象
'''
# student computer book 3类
class Computer:
def __init__(self,brand,type,color):
self.brand = brand
self.type = type
self.color = color
def online(self):
print('Connect to internet')
def __str__(self):
return self.brand + '---' + self.type + '---' + self.color
class Book:
def __init__(self,bname,author,number):
self.bname = bname
self.author = author
self.number = number
def __str__(self):
return self.bname + '---' + self.author + '---' + str(self.number)
class Student: #has a
def __init__(self,name,computer,book):
self.name = name
self.computer = computer
self.books = []
self.books.append(book)
#借书
def borrow_book(self,book):
for book1 in self.books:
if book1.bname == book.bname:
print('此书已经借阅过')
break
else:
self.books.append(book)
print(f'{book},添加成功')
def show_book(self):
for book in self.books:
print(book.bname)
def __str__(self):
return self.name + '---/' + str(self.computer) + '---/' + str(self.books)
#创建对象
computer = Computer('Huawei','MacBook','Black')
book = Book('三体','刘慈欣',3)
stu = Student('Jack',computer,book)
print(stu)
stu.show_book()
stu.borrow_book(book)
print('******************************')
book1 = Book('独臂刀客','古龙',10)
stu.borrow_book(book1)
print('------------------------')
stu.show_book()
print('******************************')
book2 = Book('流浪地球','刘慈欣',3)
stu.borrow_book(book2)
print('------------------------')
stu.show_book()
9.4 继承关系
9.4.1 父类和子类都不带任何参数的情况
'''
继承: is a base class, 也称为父类或基类
Student,Employee, Doctor --> 都属于人类
相同的代码 --》 冗余代码,可读性不高
将相同的代码提取 --》 Person 类
Student,Employee, Doctor --> 继承父类Person
class Student(Person):
pass
'''
# student Employee Doctor 3类 父类 Person
#定义父类Person
class Person:
def __init__(self):
self.name = 'Forrest'
self.age = 18
def eat(self):
print(f'{self.name} like to eat FISH')
#继承父类Person
class Student(Person):
pass
#继承父类Person
class Employee(Person):
pass
#继承父类Person
class Doctor(Person):
pass
s = Student()
s.eat()
9.4.2 带参数的情况
'''
继承: is a base class, 也称为父类或基类
Student,Employee, Doctor --> 都属于人类
相同的代码 --》 冗余代码,可读性不高
将相同的代码提取 --》 Person 类
Student,Employee, Doctor --> 继承父类Person
class Student(Person):
pass
特点:
1,如果类中不定义__init__,调用父类super class 中的__init__
2,如果类继承了父类,也定义了自己的__init__,就需要在当前类中去调用父类__init__
3,如果调用父类__init__:
super().__init__([参数])
super(类名,对象).__init__([参数])
4,如果父类有eat,子类也有eat方法,搜素的原则是先找当前类,当前类没有的话,再去找父类
s.eat()
override:重写(覆盖) --》 父类的方法无法满足子类的需求,就需要在子类定义个重名的方法
5,子类的方法中可以去调用父类的方法
super().方法名(参数)
'''
# student Employee Doctor 3类 父类 Person
#定义父类Person
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self,food):
print(f'{self.name} like to eat {food}')
#继承父类Person
class Student(Person):
def __init__(self,name,age,clazz):
print('子类的init')
#将参数传给父类的__init__
super().__init__(name,age) #super() 父类对象
#子类特有的部分
self.clazz = clazz
#override:重写
def eat(self,food,fruit):
#调用父类的方法
super(Student, self).eat(food)
#增加子类的需求
print(f'{self.name} also like to eat {fruit}')
#继承父类Person
class Employee(Person):
def __init__(self,name,age,salary,joblevel):
print('子类的init')
#将参数传给父类的__init__
super().__init__(name,age) #super() 父类对象
# 子类特有的部分
self.salary = salary
self.joblevel = joblevel
#继承父类Person
class Doctor(Person):
def __init__(self,name,age,patients):
print('子类的init')
#将参数传给父类的__init__, 加判断super(Doctor,self),等同于super()
super(Doctor,self).__init__(name,age) #super() 父类对象
# 子类特有的部分
self.patients = patients
s = Student('Jack',18,'高三一班')
s.eat('Fish','Peach')
e = Employee('Forrest',25,50000,'Ariel')
e.eat('Apple')
lists = ['Je','King','Ice','Jason']
d = Doctor('Ferry',50,lists)
d.eat('Banana')
9.5 案例
'''
编写工资管理程序:
1,系统可以管理以下四类人:
工人 worker
销售 salesman
经理 manager
销售经理 sales manager
2,所有员工都具有工号、姓名、工资等属性,有设置姓名、获取姓名、获取员工号、计算工资等方法
1)工人: 具有工作小时数和时薪的属性,工资计算方法为 工作小时数 * 时薪
2)销售:具有销售额和提成比例的属性,工资计算方法为 销售额 * 提成比例
3)经理:具有固定月薪属性,工资计算方法为 固定月薪
4)销售经理:工资计算方法为 销售额 * 提成比例 + 固定月薪
根据以上需求,完成以下功能:
1,添加所有类型的人员
2,计算月薪
3,显示所有人员的工资情况
'''
#父类
class Employee:
def __init__(self,name,eid,salary):
self.__name = name
self.__eid = eid
self.salary = salary
def getSalary(self):
return self.salary
def __str__(self):
return f'工号:{self.__eid},姓名:{self.__name},本月工资是:{self.salary}'
#worker类
class Worker(Employee):
def __init__(self,name,eid,salary,hours,hourly_rate):
super(Worker, self).__init__(name,eid,salary)
self.hours = hours
self.hourly_rate = hourly_rate
def getSalary(self):
money = self.hours * self.hourly_rate
self.salary += money
return self.salary
#销售类
class Salesman(Employee):
def __init__(self,name,eid,salary,sales_amount, percentage):
super(Salesman, self).__init__(name,eid,salary)
self.sales_amount = sales_amount
self.percentage = percentage
def getSalary(self):
money = self.sales_amount * self.percentage
self.salary += money
return self.salary
#经理类
class Manager(Employee):
def __init__(self, name, eid, salary):
super().__init__(name, eid, salary)
def getSalary(self):
super(Manager, self).getSalary()
#销售经理类
class Salesmanager(Employee):
def __init__(self, name, eid, salary,total_amount, percentage):
super().__init__(name, eid, salary)
self.total_amount = total_amount
self.percentage = percentage
def getSalary(self):
money = self.total_amount * self.percentage
self.salary += money
return self.salary
#创建对象
w = Worker('Forrest',10001, 50000,160,25)
salary = w.getSalary()
print(w)
print('-----------')
s = Salesman('Jack',10002,2000,1000000,0.003)
s.getSalary()
print(s)
print('-----------')
m = Manager('Jessie',10003,20000)
m.getSalary()
print(m)
print('-----------')
sm = Salesmanager('Jack',10004,5000,10000000,0.003)
sm.getSalary()
print(sm)
9.6 多重继承与MRO
'''
多继承与mro:
python运行多继承
def 子类(父类1,父类2,……):
pass
如果父类中有相同名称的方法,搜索顺序:
python2 深度优先 python3 广度优先
python2 : D -->C1-->P1-->P2-->object-->C2
python3 : D -->C1 -->C2 --> P1 -->P2 --> object
mro :python 查看调用顺序的内置函数
'''
#经典类
class P1:
def foo(self):
print('P1--->foo')
class P2:
def foo(self):
print('P2--->foo')
def bar(self):
print('P2--->bar')
class C1(P1,P2):
pass
class C2(P1,P2):
def bar(self):
print('C2--->bar')
class D(C1,C2):
pass
import inspect
#创建对象
d = D()
#打印搜索顺序
print(D.__mro__) #(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <class 'object'>)
print(inspect.getmro(D))
d.foo()
d.bar()
#新式类,定义class P1(object): #加上默认的继承
调用顺序如下:
9.7 多态
'''
多态:
pet 父类 cat dog 子类
per 大类型 cat dog 小类型
'''
class Person:
def __init__(self,name):
self.name = name
def raise_pet(self,pet):
#判断是否是宠物类
#isinstance(obj, 类) --》 判断obj是不是这个类的对象,或者判断obj是该类子类的对象
if isinstance(pet, Pet): #pet 既可以接收cat,dog,也可以接收tiger
print(f'{self.name}喜欢养宠物,昵称是:{pet.nickname}')
else:
print('不是宠物,千万别养……')
class Pet:
def __init__(self,nickname,age):
self.nickname = nickname
self.age = age
def show(self):
print(f'昵称:{self.nickname},年龄:{self.age}')
class Cat(Pet):
role = '猫'
def catch_mouse(self):
print('抓老鼠……')
class Dog(Pet):
role = '狗'
def watch_gate(self):
print('看门狗……')
class Tiger:
print('老虎不是宠物')
#创建对象
cat = Cat('咪咪',3)
dog = Dog('大黄',2)
tiger = Tiger()
person = Person('Jack')
person.raise_pet(cat)
print('---------')
person.raise_pet(tiger)
***************用努力照亮现实的梦!***********************
本文来自博客园,作者:逆流的鱼2016,转载请注明原文链接:https://www.cnblogs.com/orange2016/p/16477630.html