类的继承

基本概念

定义

格式如下

继承中的访问控制

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. 利用Bootstrap Paginator插件和KnockoutJS完成分页功能

    在最近一个项目中,需要结合一堆条件查询并对查询的结果数据完成一个简单分页功能,可是做着做着,自己的思路越来越模糊,做到心态崩溃!!! 哈哈,特此花点时间重新总结,并从最简单的分页,然后向多条件查询分页 ...

  2. Java~命名规范

    下面总结以点java命名规范 虽然感觉这些规范比起C#来说有点怪,但还是应该尊重它的命名! 命名规范 项目名全部小写 包名全部小写 类名首字母大写,如果类名由多个单词组成,每个单词的首字母都要大写. ...

  3. 并发系列(4)之 AbstractQueuedSynchronizer 源码分析

    本文将主要讲述 AbstractQueuedSynchronizer 的内部结构和实现逻辑,在看本文之前最好先了解一下 CLH 队列锁,AbstractQueuedSynchronizer 就是根据 ...

  4. SLAM+语音机器人DIY系列:(三)感知与大脑——1.ydlidar-x4激光雷达

    摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...

  5. 了解AJAX

    1.如何打开终端的快捷键 Window+R==>CMD==>ipconfig 动态页面:跟后台发生数据交互的页面. 前后台数据交互依赖的一项技术叫 ajax. 1. js的异步操作 (1) ...

  6. Spring+MyBatis整合过程

    步骤: 1.引入Spring+MyBatis开发包 >spring(ioc aop dao)开发包 >mybatis开发包,dbcp,驱动包 >mybatis-spring.jar整 ...

  7. 一种动态写入apk数据的方法(用于用户关系绑定、添加渠道号等)

    背景: 正在开发的APP需要记录业务员与客户的绑定关系.具体应用场景如下: 由流程图可知,并没有用户填写业务人员信息这一步,因此在用户下载的APP中就已经携带了业务人员的信息. 由于业务人员众多,不可 ...

  8. RAID5当一块硬盘离线后处理

    RAID5当一块硬盘离线后,处理降级状态,这时候正常的建议是马上更换硬盘做REBUILD以恢复完整的数据状态,如果有热备盘的话,就会自动做REBUILD,这样做合适吗? 一组RAID卷在工作很长时间以 ...

  9. 在xp下无人值守自动安装系统

    无人值守安装可以大大缩短安装系统的时间.我在虚拟机测试成功. 先给文件链接https://files.cnblogs.com/files/sishenzaixian/%E8%87%AA%E5%8A%A ...

  10. Jdk 接口类RandomAccess了解

    1. 接口说明 Marker interface used by List implementations to indicate that they support fast (generally ...