类的继承

基本概念

定义

格式如下

继承中的访问控制

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. DotNetCore跨平台~EFCore废弃了TransactionScope取而代之的Context.Database.BeginTransaction

    回到目录 TransactionScope是.net平台基于的分布式事务组件,它默认为本地事务,同时当系统有需要时可以自动提升为分布式事务,而对系统的前提是要开启MSDTC服务,必要时需要在数据库服务 ...

  2. Docker进阶之五:容器管理

    容器管理 一.创建容器常用选项 docker container --help 指令 描述 资源限制指令 -i, --interactive 交互式 -m,--memory 容器可以使用的最大内存量 ...

  3. springcloud情操陶冶-springcloud config server(二)

    承接前文springcloud情操陶冶-springcloud config server(一),本文将在前文的基础上讲解config server的涉外接口 前话 通过前文笔者得知,cloud co ...

  4. 树莓派linux系统连接windows7系统中的共享文件夹的正确姿势

    一.要想使用树莓派linux成功访问win7的共享文件夹而不报错,最重要的事情是要正确设置win7中共享文件的设置. 1.需要共享文件点击右键→属性 2.共享选项卡→网络和共享中心 3.点开公用下拉菜 ...

  5. C# 因缺少CategoryName,而未能初始化 的解决办法

    群里一小伙伴在开发APP时遇到了问题,便截图提问 一.傻瓜式解决办法: 删除: ((System.ComponentModel.ISupportInitialize)(this.performance ...

  6. DSAPI 键盘鼠标钩子

    通常,说到Hook键盘鼠标,总需要一大堆代码,涉及各种不明白的API.而在DSAPI中,可以说已经把勾子简化到不能再简化的地步.甚至不需要任何示例代码即会使用.那么如何实现呢? Private Wit ...

  7. vs2015安装编辑神器:resharper10.0

    在平时的开发工作中,作为一名程序员,难免会想办法找到适合自己的开发编辑器.这款插件来自JetBrains公司.接下来就来教大家如何对这款软件进行安装与破解. 1:首先下载与安装.如果没有找到适合的资源 ...

  8. Ubuntu16.04安装RealSense SR300驱动

    原文链接 https://blog.csdn.net/u013401766/article/details/78472285 第一步:CMake 3.14.0 安装 1)下载cmake-3.14.1. ...

  9. HTML5之webSocket使用

    webSocket是什么 webSocket是HTML5新出的一种协议,底层是基于TCP/IP协议的.跟http没有关系,只是复用了http握手通道,用来升级协议. webSocket的作用 轮询:客 ...

  10. 详解块级格式化上下文(BFC)

    相信大家和我一样,第一次听到别人说CSS 块级格式化上下文(block formatting context,简称:BFC)的时候一头雾水,为了帮助大家弄清楚块级格式化上下文,我翻阅了W3C的CSS规 ...