面对对象进阶
Posted zuihoudebieli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面对对象进阶相关的知识,希望对你有一定的参考价值。
面对对象进阶
类的继承
python当中,父类和子类(派生类),父类和子类只有在继承的时候才会产生
继承是为了拿到父类的所有东西
class Parent_Foo: #父类
def __init__(self, first_name, money, car, house):
self.first_name = first_name
self.money = money * 0.5
print('继承财产扣掉一半')
self.car = car
self.house = house
def find_wife(self):
print(f'self.first_name先生找到妻子白富美')
# pf = Parent_Foo('??', -1, 'tesla', '上海汤臣一品1栋')
class Son_Foo(Parent_Foo): #子类
pass
sf = Son_Foo('??', 1000, 'tesla', '上海汤臣一品1栋') #子类继承父类的所有东西
print(sf.first_name)
print(sf.money)
print(sf.car)
print(sf.house)
sf.find_wife()
继承财产扣掉一半
猪
1000
tesla
shanghai汤臣一品1栋
猪先生找到妻子白富美
class Animal(): #父类
def __init__(self, height, weight):
self.height = height
self.weight = weight
def jiao(self):
print(self.__class__.__name__, '叫')
class XingXing(): #父类
def sleep(self):
print('睡觉')
class People(Animal, XingXing): #子类
def read(self): #功能
print('read')
def jiao(self): #类的功能
print('jiao')
aobama = People(170, 120)
aobama.jiao()
aobama.sleep()
meixi = People(168, 140)
meixi.jiao()
class Dog(Animal):
def eat_shi(self):
print('eat_shi')
shinubi = Dog(40, 50)
shinubi.jiao()
jiao
睡觉
jiao
Dog 叫
不推荐使用继承,当你继承多个的时候,功能与功能之间会混乱,顶多继承一个
继承后查找顺序:先自己,再类,在父类,再父类,在父类,在父类的父类
class Foo: #父类
def f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
self.f1()
class Bar(Foo): #子类
def f1(self):
print('Bar.f1')
b = Bar()
print(b.__dict__) #
b.f2() #Foo.f2 Bar.f1
类的派生
类的派生:添加新的属性的同时还有继承父类的所有东西
派生:继承父类属性的同时增加新的属性,然后使用super().__init__()
class Animal():
def __init__(self, height, weight): # self给对象,self=peo,180,140
self.height = height # peo.height = 180
self.weight = weight # peo.weight = 140
def jiao(self):
print(self.__class__.__name__, '叫')
class XingXing(Animal): #继承
def __init__(self, gender,height, weight):
super().__init__(height, weight) #继承上一个的参数
self.gender = gender
def sleep(self):
print('睡觉')
class People(XingXing): #继承
def __init__(self,name,age,height,weight,gender):
super().__init__(height,weight,gender) #继承上一个的参数
self.name = name
self.age = age
def read(self):
print('read')
def jiao(self):
print('jiao')
peo = People('nick',18,180,140,'male') #
print(peo.__dict__)
类的组合
组合:组合在一起
# 简单的选课系统
class People: #父类 人类
def __init__(self, name, gender):
self.name = name
self.gender = gender
def eat(self): #技能: 吃
print(f'self.name开始吃了')
class Student(People): #子类 学生
def __init__(self, student_id, name, gender): #属性特征 学号,姓名,性别
self.student_id = student_id
super(Student, self).__init__(name, gender)
def choose_course(self, course): # python对象 选择课程 课程类当参数传入
self.course = course # 组合 # 把对象当作变量值来用,当作形参/实参/返回值。
print(f'self.name选课course.name成功')
class Teacher(People): #子集 教师
def __init__(self, level, name, gender): #属性 级别,性别
self.level = level
super(Teacher, self).__init__(name, gender) #从人类中派生姓名,级别
def scored(self, student, course, score): #技能,评分 课程类当参数传入
print(f'老师self.name给student.name课程course.name打分score')
class Course: #课程 一个类
def __init__(self, name, price):
self.name = name
self.price = price
class Admin(People): #子类 管理员
def create_course(self, name, price): #属性 姓名,价格
course = Course(name, price) #调用了Course课程类
print(f'管理员self.name创建了课程name')
return course
# 课程
# python = Course('Python', '8888')
# linux = Course('Linux', '6666')
# 学生
zhubajie = Student('01', 'zhubajie', 'male')
sunwukong = Student('02', 'sunwukong', 'male')
# 老师
nick = Teacher('1', 'nick', 'male')
tank = Teacher('2', 'tank', 'female')
# 管理员
egon = Admin('egon', 'male')
# 业务逻辑
# 1. 创建课程
python = egon.create_course('python', '8888') #管理员egon创建了课程python
print(python.__dict__) #'name': 'python', 'price': '99999'
linux = egon.create_course('linux', '6666') #管理员egon创建了课程linux
print(linux.__dict__) #'name': 'linux', 'price': '66666'
# 2. 学生选择课程
zhubajie.choose_course(python) #zhubajie选课python
# 3. 老师给学生打分
nick.scored(zhubajie,python,'0') #老师nick给zhubajie课程python打分0
菱形继承问题
在python2当中不会默认继承类,必须得子集手动添加
新式类:只要继承了object类的就是新式类,python3当中所有的类都是新式类
经典类:没有继承object类的就是经典类,只有python2当中有经典类
当即继承为菱形继承的时候,经典类和新式类搜索某一个属性的顺序会不一样
在新式类中,当遇到菱形继承时,会以广度优先查找
在经典类中,当遇到菱形继承时,会以深度优先查找
普通继承时,就是正常顺序找
class G:
def text(self):
print('from G')
class F(G):
def text(self):
print('from F')
class E(G):
# def text(self):
# print('from E')
pass
class D(G):
def text(self):
print('from D')
class C(F):
def text(self):
print('from C')
class B(E):
# def text(self):
# print('from B')
pass
class A(B,C,D):
# def text(self):
# print('from A')
pass
a = A()
a.text()
for i in A.__mro__:
print(i)
from C
<class '__main__.A'>
<class '__main__.B'>
<class '__main__.E'>
<class '__main__.C'>
<class '__main__.F'>
<class '__main__.D'>
<class '__main__.G'>
<class 'object'>
多态和对多态性
import abc
class Animal(metaclass=abc.ABCMeta):
def __init__(self,height,weight):
self.height = height
self.weight = weight
# @abc.abstractmethod
def sleep(self):
print('我在睡觉')
@abc.abstractmethod
def speak(self):
print(self,'开始叫了')
@abc.abstractmethod
def eat(self):
print(self,'开始吃了')
class People(Animal):
def speak(self):
print('开始叫了')
def eat(self):
print(self,'开始吃了')
class Dog(Animal):
def speak(self):
print('开始叫了')
def eat(self):
print(self,'开始吃了')
class Cow(Animal):
def speak(self):
print('开始叫了')
def eat(self):
print(self,'开始吃了')
peo = People(180,140)
dog = Dog(50,100)
cow = Cow(100,200)
peo.speak()
dog.sleep()
cow.sleep()
# sheep.speak()
# mao.speak()
peo.eat()
dog.eat()
import abc
class Animal(metaclass=abc.ABCMeta):
def __init__(self,height,weight):
self.height = height
self.weight = weight
# @abc.abstractmethod
def sleep(self):
print('我在睡觉')
@abc.abstractmethod
def speak(self): #以animal为父类的子类中必须有speak,才可以运行
print(self,'开始叫了')
@abc.abstractmethod
def eat(self): #以animal为父类的子类中必须有eat,才可以运行
print(self,'开始吃了')
class Foo(Animal): #定义动物类
def speak(self): #技能 讲话 没有eat技能
pass
f = Foo(1,1) #运行类,类属性赋值 身高,体重
f.sleep() #运行父类中的技能报错,因为没有eat技能
鸭子类型:长的像鸭子,叫声也像鸭子,就是鸭子,(只要有speak和eat两种方法,那他就是动物类)
对于我们这个例子,你只要有speak/有eat方法,我无论你怎么定义这个类,你就是动物的一种形态,你这样才能用动物的方法,否则无法使用动物的方法
以上是关于面对对象进阶的主要内容,如果未能解决你的问题,请参考以下文章