类的继承

基本概念

定义

格式如下

继承中的访问控制

class Animal:
__CNOUT = 0
HEIGHT = 0 def __init__(self,age,weight,height):
self.__CNOUT =self.__CNOUT + 1
self.age = age
self.__weight = weight
self.HEIGHT = height def eat(self):
print('{} eat'.format(self.__class__.__name__)) def __getweight(self):
print(self.__weight) @classmethod
def showcount1(cls):
print(cls.__CNOUT) @classmethod
def __showcount2(cls):
print(cls.__CNOUT) class Cat(Animal):
NAME = 'CAT' c = Cat(3,5,15)
c.eat()
c.showcount1()#注意此处的cls.__COUNT仍为0 print(c.NAME)
print(c.__dict__)#{'_Animal__CNOUT': 1, 'age': 3, '_Animal__weight': 5, 'HEIGHT': 15}
print(Cat.__dict__)#{'__module__': '__main__', 'NAME': 'CAT', '__doc__': None}
print(Animal.__dict__)#{'__module__': '__main__', '_Animal__CNOUT': 0, 'HEIGHT': 0,...}

方法的重写、覆盖override

class Animal:
def shout(self):
print('Animal shout') class Cat(Animal):
#覆盖父类的方法
def shout(self):
print('miao')
#覆盖自身的方法,显示调用了父类的方法
def shout(self):
print(super(Cat, self))
super().shout() a = Animal()
a.shout()
c =Cat()
c.shout() #输出结果:
# Animal shout
# <super: <class 'Cat'>, <Cat object>>
# Animal shout

class Animal:
@classmethod
def class_method(cls):
print('class_method_animal') @staticmethod
def static_method():
print('static_method_animal') class Cat(Animal):
@classmethod
def class_method(cls):
print('class_method_cat') @staticmethod
def static_method():
print('static_method_cat') c = Cat()
c.class_method()
c.static_method()
#输出结果:
# class_method_cat
# static_method_cat

继承中的初始化

示例1

class A:
def __init__(self):
self.a1 = 'a1'
self.__a2 = 's2'
print('A init') class B(A):
pass
b = B()
print(b.__dict__) #{'a1': 'a1', '_A__a2': 's2'}

示例2

class A:
def __init__(self):
self.a1 = 'a1'
self.__a2 = 's2'
print('A init') class B(A):
def __init__(self):
self.b1 = 'b1'
print('B init')
b = B()
print(b.__dict__) #{'b1': 'b1'}

class A:
def __init__(self):
self.a1 = 'a1'
self.__a2 = 's2'
print('A init') class B(A):
def __init__(self):
# A.__init__(self)
# super(B,self).__init__()
super().__init__()
self.b1 = 'b1'
print('B init')
b = B()
print(b.__dict__) #{'a1': 'a1', '_A__a2': 's2', 'b1': 'b1'}

如何正确初始化

 

class Animal:
def __init__(self,age):
print('Animal init')
self.age =age def show(self):
print(self.age) class Cat(Animal):
def __init__(self,age,weight):
super().__init__(age)#c.show()结果为11
print('Cat init')
self.age = age + 1
self.weight = weight
# super().__init__(age)#c.show()结果为10
c = Cat(10,5)
c.show()
# c.__dict__ {'age': 11, 'weight': 5}

class Animal:
def __init__(self,age):
print('Animal init')
self.__age =age def show(self):
print(self.__age) class Cat(Animal):
def __init__(self,age,weight):
super().__init__(age)
print('Cat init')
self.__age = age + 1
self.__weight = weight
c = Cat(10,5)
c.show()
print(c.__dict__)#{'_Animal__age': 10, '_Cat__age': 11, '_Cat__weight': 5}

Python不同版本的类

多继承

多继承弊端

Python多继承实现

class ClassName(基类列表):
类体

多继承的缺点

Mixin

class Printable:
def _print(self):
print(self.content) class Document:#假设为第三方库,不允许修改
def __init__(self,content):
self.content = content class Word(Document):pass#假设为第三方库,不允许修改
class Pdf(Document):pass#假设为第三方库,不允许修改 class PrintableWord(Printable,Word):pass
print(PrintableWord.__dict__)
print(PrintableWord.mro())
pw = PrintableWord('test string')
pw._print()

def printable(cls):
def _print(self):
print(self.content,'装饰器')
cls.print = _print
return cls class Document:#假设为第三方库,不允许修改
def __init__(self,content):
self.content = content class Word(Document):pass#假设为第三方库,不允许修改
class Pdf(Document):pass#假设为第三方库,不允许修改 @printable
class PrintableWord(Word):pass print(PrintableWord.__dict__)#{'__module__': '__main__', '__doc__': None, 'print': <function printable.<locals>._print at 0x0000000002961730>}
PrintableWord('test').print()#test 装饰器

4.Mixin

#Mixin示例1
class PrintableMixin:
def print(self):
print(self.content,'Mixin') class Document:
def __init__(self,content):
self.content = content class Word(Document):pass
class Pdf(Document):pass class PrintableWord(PrintableMixin,Word):pass
print(PrintableWord.__dict__)
print(PrintableWord.mro()) pw = PrintableWord('test\nstring')
pw.print()

#Mixin示例2
class PrintableMixin:
def print(self):
print(self.content,'Mixin') class Document:
def __init__(self,content):
self.content = content class Word(Document):pass
class Pdf(Document):pass class SuperPrintableMixin(PrintableMixin):
def print(self):
print('~'*20)
super().print() #通过继承复用
print('~'*20) class SuperPrintablePdf(SuperPrintableMixin,Pdf):pass
print(SuperPrintablePdf.__dict__)
print(SuperPrintablePdf.mro()) spp = SuperPrintablePdf('super print pdf')
spp.print()

Mixin类

练习

#1.Shape基类,要求所有子类都必须提供面积的计算,子类有三角形、矩形、圆
import math class Shape:
@property
def area(self):
raise NotImplementedError('基类未实现') class Triangle(Shape):
def __init__(self,a,b,c):
self.a = a
self.b = b
self.c = c @property
def area(self):
p = (self.a+self.b+self.c)/2
return math.sqrt(p*(p-self.a)*(p-self.b)*(p-self.c)) class Circle(Shape):
def __init__(self,radius):
self.radius = radius @property
def area(self):
return math.pi*self.radius**2 class Rectangle(Shape):
def __init__(self,width,height):
self.width = width
self.height = height @property
def area(self):
return self.width*self.height # shapes = [Triangle(3,4,5),Rectangle(3,4),Circle(4)]
# for s in shapes:
# print('The area of {} = {}'.format(s.__class__.__name__,s.area)) #2.圆类的数据可序列化
import json
import msgpack def mydump(cls):
def _dumps(self, t='json'):
if t == 'json':
return json.dumps(self.__dict__)
elif t == 'msgpack':
return msgpack.packb(self.__dict__)
else:
raise NotImplementedError('没有实现的序列化')
cls.dumps = _dumps
return cls #使用Mixin类
# class SerializableMixin:
# def dumps(self,t='json'):
# if t == 'json':
# return json.dumps(self.__dict__)
# elif t == 'msgpack':
# return msgpack.packb(self.__dict__)
# else:
# raise NotImplementedError('没有实现的序列化')
#
#使用装饰器
@mydump
class SerializableCircleMixin(Circle):pass scm = SerializableCircleMixin(1)
print(scm.area)#3.141592653589793
print(scm.__dict__)#{'radius': 1}
print(scm.dumps('json'))#{"radius": 1}

 作业

#单链表
class SingleNode:
#代表一个节点
def __init__(self,val,next=None):
self.val = val
self.next = None class LinkedList:
#容器类,某种方式存储一个个节点
def __init__(self):
self.head = None
self.tail = None def append(self,val):
node = SingleNode(val)
if self.head is None:#
self.head = node
self.tail = node
self.tail.next = node
self.tail = node def iternodes(self):
while self.head:
yield self.head.val
self.head = self.head.next
 #实现双向链表
class SingleNode:
#代表一个节点
def __init__(self,val,next=None,prev=None):
self.val = val
self.next = next
self.prev = prev def __repr__(self):
return str(self.val) class LinkedList:
#容器类,某种方式存储一个个节点
def __init__(self):
self.head = None
self.tail = None def append(self,val):
node = SingleNode(val)
if self.head is None:#
self.head = node
else:
self.tail.next = node
node.prev = self.tail
self.tail = node def pop(self):
if self.tail is None:#
raise NotImplementedError('Empty')
tail = self.tail
prev= self.tail.prev
if prev is None:#1个节点
self.head = None
self.tail = None
else:#>1
self.tail = prev
prev.next = None
return tail.val def insert(self,index,val):#1,7
if index < 0:
raise Exception('Error')
cur = None
for i,current in enumerate(self.iternodes()):
if i == index:
cur = current
break if cur is None:#说明索引越界或空链表,直接末尾追加
self.append(val)
return node = SingleNode(val)
prev = cur.prev
if prev is None:#1个节点,头部插入
self.head = node
node.next = cur
cur.prev = node
else:#>=2
node.next = cur
prev.next = node
cur.prev = node
node.prev = prev def iternodes(self,reversed = False):
current = self.head
while current:
yield current
current = current.next a = SingleNode(1)
b = SingleNode(2)
c = SingleNode(3)
d = SingleNode(4)
e = SingleNode(5)
f = SingleNode(6)
ll = LinkedList()
ll.append(a)
ll.append(b)
ll.append(c)
ll.append(d)
ll.append(e)
ll.append(f)
# ll.insert(1,0)
# ll.insert(0,0)
ll.insert(10,100)
print('pop元素:',ll.pop())
print('pop元素:',ll.pop())
print('pop元素:',ll.pop())
ll.insert(0,10) for node in ll.iternodes():
print(node)

Pyhon进阶9---类的继承的更多相关文章

  1. Python类的继承(进阶5)

    转载请标明出处: http://www.cnblogs.com/why168888/p/6411918.html 本文出自:[Edwin博客园] Python类的继承(进阶5) 1. python中什 ...

  2. 苹果新的编程语言 Swift 语言进阶(十)--类的继承

    一.类的继承 类能够从其它类继承方法.属性以及其它特性,当一个类从另外的类继承时,继承的类称为子类,它继承的类称为超类.在Swift中,继承是类区别与其它类型(结构.枚举)的基础行为. 1.1 .类的 ...

  3. Java+7入门经典 - 6 扩展类与继承 Part 1/2

    第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...

  4. 游戏编程之Unity常用脚本类的继承关系

    前言学习Unity开发引擎的初学者会接触大量的脚本类,而这些类之间的关系往往容易被忽略.本文对Unity引擎开发中的一些常用类及其关系进行了简单的归纳总结. 博文首发地址:http://tieba.b ...

  5. Objective-C编程 — 类和继承

    讲述面向对象中的一个重要概念——继承,使用继承 可以方便地在已有类的基础上进行扩展,定义一个具有父 类全部功能的新类. 父类和子类 我们在定义一个新类的时候,经常会遇到要定义的新类是某个类的扩展或者是 ...

  6. Java基础进阶:时间类要点摘要,时间Date类实现格式化与解析源码实现详解,LocalDateTime时间类格式化与解析源码实现详解,Period,Duration获取时间间隔与源码实现,程序异常解析与处理方式

    要点摘要 课堂笔记 日期相关 JDK7 日期类-Date 概述 表示一个时间点对象,这个时间点是以1970年1月1日为参考点; 作用 可以通过该类的对象,表示一个时间,并面向对象操作时间; 构造方法 ...

  7. C++学习笔记:07 类的继承与派生

    课程<C++语言程序设计进阶>清华大学 郑莉老师) 基本概念 继承与派生的区别: 继承:保持已有类的特性而构造新类的过程称为继承. 派生:在已有类的基础上新增自己的特性(函数方法.数据成员 ...

  8. UML类图(上):类、继承和实现

    面向对象设计 对于一个程序员来说,在工作的开始阶段通常都是别人把东西设计好,你来做.伴随着个人的成长,这个过程将慢慢变成自己设计一部分功能来实现,自己实现.如果要自己设计,无论是给自己看,还是给别人看 ...

  9. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

随机推荐

  1. SpringBoot技术栈搭建个人博客【后台开发】

    前言:在之前,我们已经完成了项目的基本准备,那么就可以开始后台开发了,突然又想到一个问题,就是准备的时候只是设计了前台的RESTful APIs,但是后台管理我们同样也是需要API的,那么就在这一篇里 ...

  2. 浅谈Promise

    学习过JavaScript的人都知道,JavaScript是单线程作业,这样会有一个很大的缺陷,所有的Ajax,浏览器事件等,都是通过异步去完成.所谓的同步和异步最大的区别无非就是在于同步会阻塞后续代 ...

  3. 【Vue.js】代码优化:在dom中加一行v-if就可少写一个循环类方法

    [问题描述] 把当前用户的购物车中(cartList),商品(good)选中字段checked = true的商品在订单页面中进行展示出来. [一般做法](两次循环) 首先取出当前用户的购物车列表,循 ...

  4. Cayley图数据库的简介及使用

    图数据库   在如今数据库群雄逐鹿的时代中,非关系型数据库(NoSQL)已经占据了半壁江山,而图数据库(Graph Database)更是攻城略地,成为其中的佼佼者.   所谓图数据库,它应用图理论( ...

  5. linux 指令备忘

    linux 指令备忘 1.ls [选项] [目录名 | 列出相关目录下的所有目录和文件 -a 列出包括.a开头的隐藏文件的所有文件 -A 通-a,但不列出"."和"..& ...

  6. 【转载】Mysql创建表时报错error150

    从mysql数据库中导出正常数据库的脚本语句,而后使用脚本语句创建数据库的过程中,执行语句提示Can't Create Table 'XXX' erro150的错误,语句执行中断,创建table失败, ...

  7. java类的继承(基础)

    ---恢复内容开始--- 这篇随笔和大家讲讲java中类的继承是什么?希望对你们有所帮助. 目录 一.java继承是什么? 二.为什么使用java继承 三.java继承的实现 1.1  java继承的 ...

  8. Android 视频通信,低延时解决方案

    背景: 由于,项目需要,需要进行视频通信,把a的画面,转给b. 运维部署: APP1:编码摄像头采集的数据,并且发送数据到服务端 APP2:从服务端,拉取数据,并且进行解码显示 服务端:接收APP1提 ...

  9. CMMI 2.0术语变化

    过程域 vs. 实践域 “过程域”(Process Areas,PAs)在CMMI 2.0中变成了“实践域(Practice Areas,PAs)”.这样的改变,强调了CMMI 2.0是最佳实践的集合 ...

  10. powershell-脚本运行权限政策

    获取当前策略:Get-ExecutionPolicy 设置当前策略:Set-ExecutionPolicy Unrestricted Restricted——默认的设置, 不允许任何script运行 ...