python高级-面向对象特性(12)
一、继承的概念
在现实生活中,继承一般指的是子女继承父辈的财产,在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物;同理,波斯猫和巴厘猫都继承自猫,而沙皮狗和斑点狗都继承足够,如下如所示:
二、继承的示例
class Cat(object):
def __init__(self,name,color="白色"):
self.name = name
self.color = color def run(self):
print("%s:在跑"%self.name) class Bosi(Cat):
def setNewName(self,newName):
self.name = newName def eat(self):
print("%s:在吃"%self.name) bs = Bosi("波斯猫")
print("bs的名字是:%s,颜色是:%s"%(bs.name,bs.color))
bs.eat()
bs.setNewName("汤姆猫")
bs.run()
运行结果为:
bs的名字是:波斯猫,颜色是:白色
波斯猫:在吃
汤姆猫:在跑
说明:
- 虽然子类没有定义__init__()方法,但是父类有。所以在子类集成父类的时候这个方法就被继承了,所以只要创建Bosi的对象,就默认执行了那个继承过来的__init__()方法
- 子类在继承的时候,在定义类时,小括号()中为父类的名字
- 父类的所有非私有的属性、方法、会被继承给子类
注意:
- 私有的属性,不能通过对象直接访问,但是可以通过方法访问
- 私有的方法,不能通过对象直接访问
- 私有的属性、方法,不会被子类继承,也不能被访问
- 一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用
class Animal(object):
def __init__(self, name = "动物",color = "白色"):
self.__name = name
self.color = color def __test1(self):
print(self.__name)
print(self.color) def test2(self):
print(self.__name)
print(self.color) class Dog(Animal):
def dogTest1(self):
#不能访问父类的私有属性:AttributeError: 'Animal' object has no attribute '__name'
#print(self.__name)
print(self.color) def dogTest2(self):
#self.__test1()
self.test2() A = Animal()
#print(A.__name)
print(A.color)
#不能访问父类的私有方法:AttributeError: 'Animal' object has no attribute '__test1'
#A.__test1()
A.test2() print("-----------------分割线-----------------")
D = Dog(name="阿黄",color = "黄色")
D.dogTest1()
D.dogTest2()
运行结果为:
白色
动物
白色
-----------------分割线-----------------
黄色
阿黄
黄色
三、多继承
从图中能够看出,所谓多继承,即子类有多个父类,并且具有它们的特征
Python中多继承的格式如下:
class A:
def printA(self):
print("---A---") class B:
def printB(self):
print("---B---") #定义一个子类继承A,B
class C(A,B):
def printC(self):
print("---C---") obj_C = C()
obj_C.printA()
obj_C.printB()
运行结果为:
---A---
---B---
说明
- python中是可以多继承的
- 父类中的方法、属性,子类会继承
- 如果多个父类中有同一个方法,谁写在前面就调用谁的方法
class A:
def printA(self):
print("---A---") class B:
def printB(self):
print("---B---") #定义一个子类继承A,B
class C(A,B):
def printC(self):
print("---C---") obj_C = C()
obj_C.printA()
obj_C.printB()
#可以查看一个雷的对象搜索方法时的先后顺序
print(C.__mro__)
运行结果为:
---A---
---B---
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
四、重写父类方法与调用父类方法
1、重写父类方法
所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法
class Cat(object):
def sayHello(self):
print("Hello:Cat") class Bosi(Cat):
def sayHello(self):
print("Hello:Bosi") bs = Bosi()
bs.sayHello()
运行结果为:Hello:Bosi
2、调用父类方法
class Cat(object):
def __init__(self,name):
self.name = name
self.color = "黄色" class Bosi(Cat):
def __init__(self,name):
#Cat.__init__(self,name) #python2的语法
#调用父类的方法
super().__init__(name) def getName(self):
return self.name
pass bs = Bosi("波斯")
print(bs.name)
print(bs.color)
运行结果为:
波斯
黄色
五、多态
- 多态的概念是应用于Java和C#这一类强类型语言中
- 所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态
class F1(object):
def show(self):
print("F1.show") class S1(F1):
def show(self):
print("S1.show") class S2(object):
def show(self):
print("S2.show") def func(obj):
obj.show() s1_obj = S1()
func(s1_obj) s2_obj = S2()
func(s2_obj)
运行结果为:S1.show、S2.show
六、类属性、实例属性
了解类基本的东西之后,下面看一下python中这几个概念的区别、
在前面的例子中我们接触到的就是实例属性(对象属性),类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问
1、类属性
class Person(object):
name = "Tom" #公有的类属性
__age = 12 #私有的类属性 p = Person() print(p.name) #正确
print(Person.name) #正确 #print(p.__age) #错误,不能再类外通过实例变量访问类的私有属性
#print(Person.__age) #错误,不能再类外通过类对象访问类的私有属性
运行结果为:Tom、Tom
2、实例属性(对象属性)
class Person(object):
address = "广州"
def __init__(self):
self.name = "Se7eN_HOU"
self.age = 29 p = Person()
p.age = 18 #实例属性
print(p.name) #正确
print(p.address) #正确。实例对象可以访问类属性
print(p.age) #正确 print(Person.address) #正确
#print(Person.name) #错误,类不能访问实例属性
#print(Person.age) #错误,类不能访问实例属性
运行结果为:
Se7eN_HOU
广州
18
广州
3、通过实例去修改类属性
class Person(object):
address = "广州" #类属性 p = Person() print(p.address) #正确
print(Person.address) #正确 print("-------分界线--------") p.address = "北京"
print(p.address)
print(Person.address) print("-------分界线--------") Person.address = "上海"
print(p.address)
print(Person.address)
运行结果为:
广州
广州
-------分界线--------
北京
广州
-------分界线--------
北京
上海
说明:
- 如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。
- 如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性。
- 如果通过实例对象去引用该类的类的属性,实例属性其实会重新创建一个新的属性。
七、类方法
类方法:是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以’cls’作为第一个参数的名字,就最好用’cls’了),能够通过实例对象和类对象去访问。
class Person(object):
country = "china" @classmethod
def getCountry(cls):
return cls.country p = Person()
print(p.getCountry()) #正确,实例对象可以调用类方法
print(Person.getCountry())
运行结果为:china、china
类方法还有一个用途就是可以对类属性进行修改:
class Person(object):
country = "china" @classmethod
def getCountry(cls):
return cls.country @classmethod
def setCountry(cls,newCountry):
cls.country = newCountry p = Person()
print(p.getCountry()) #正确,实例对象可以调用类方法
print(Person.getCountry()) p.setCountry("CHINA")
print(p.getCountry()) Person.setCountry("中国")
print(Person.getCountry())
运行结果为:
china
china
CHINA
中国
结果显示在用类方法对类属性修改之后,通过类对象和实例对象访问都发生了改变
八、静态方法
静态方法:需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数
class Person(object):
country = "china" @staticmethod
def getCountry():
return Person.country p = Person()
print(p.getCountry())
print(Person.getCountry())
运行结果为:china、china
总结:
实例方法:
- 定义:第一个参数必须是实例对象,该参数名一般约定为“self”,通过它来传递实例的属性和方法(也可以传类的属性和方法);
- 调用:只能由实例对象调用。
类方法:
- 定义:使用装饰器@classmethod。
- 第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);
- 调用:实例对象和类对象都可以调用。
静态方法:
- 定义:使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法;
- 调用:实例对象和类对象都可以调用。
python高级-面向对象特性(12)的更多相关文章
- JavaScript高级 面向对象(12)--引用类型值类型作为参数传递的特性
说明(2017-4-2 18:27:11): 1. 作为函数的参数,就是将函数的数据拷贝一份,传递给函数的定义中的参数. 函数foo()在调用的时候,做了两件事: (1)函数在调用的时候,首先需要将参 ...
- python高级-面向对象(11)
一.面向过程和面向对象 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 二.类和对象 1.类的概念 面向对象编程的 ...
- python高级-动态特性(20)
一.动态语⾔的定义 动态语言是在运行时确定数据类型的语言.变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型.现在比较热门的动态语言有:Python.PHP.JavaScript.Obj ...
- Python 高级面向对象
一.字段 1.字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同. a.普通字段属于对象(实例变量) b.静态字段属于类(类变量) 二.属性 对于属性,有以 ...
- 第四篇:python 高级之面向对象初级
python 高级之面向对象初级 python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 ...
- python 高级之面向对象初级
python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 面向对象:对函数进行分类和封装,让开 ...
- Python高级特性(3): Classes和Metaclasses(转)
原文:Python高级特性(3): Classes和Metaclasses 类和对象 类和函数一样都是Python中的对象.当一个类定义完成之后,Python将创建一个“类对象”并将其赋值给一个同名变 ...
- Python高级特性(2):Closures、Decorators和functools(转)
原文:Python高级特性(2):Closures.Decorators和functools 装饰器(Decorators) 装饰器是这样一种设计模式:如果一个类希望添加其他类的一些功能,而不希望通过 ...
- Python高级特性(1):Iterators、Generators和itertools(转)
译文:Python高级特性(1):Iterators.Generators和itertools [译注]:作为一门动态脚本语言,Python 对编程初学者而言很友好,丰富的第三方库能够给使用者带来很大 ...
随机推荐
- WinForm DotNetBar 动态添加DataGridView
DataGridView dgv = new DataGridView(); dgv.Dock = DockStyle.Fill; dgv.Location = new System.Drawing. ...
- Delphi之Exception获得错误信息
1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Con ...
- oracle中的日期函数的使用
TO_DATE格式(以时间:2007-11-02 13:45:25为例) Year: yy two digits 两位年 显示值:07 ...
- Golang之路【目录】
我正在写一套使用Golang全栈开发的教程,名字暂叫“Golang之路”,希望大家多提建议. 目录如下: Golang之路[第一篇]:Golang简介和入门Golang之路[第二篇]:Golang基础 ...
- Alpha冲刺四
第四天 日期:2018/6/19 1.1 今日完成任务情况以及遇到的问题. 成员 汝春瑞.曹 阳 赵红波.梁玉龙 傅 康.丁炜轩 今日完成任务 设计餐厅每个店家的餐品界面 完成公告和失物招领 ...
- Cordova配置与WebApp混合开发环境配置
好久都没来更新随笔了,这阵子比较忙,不过还是在不断的学习当中,今天给大家分享一下Cordova的配置与搭建WebApp混合开发环境的配置. 准备好了吗?让我们一步步来咯!!! 1.配置JDK环境 用的 ...
- linu输出重定向
1.tee命令 ls | tee filename #若出现Permission Denied使用下面 ls | sudo tee filename #清空filename后重写 ls | sudo ...
- C#中get和set属性的作用
c#在定义类时,通常要把类中声明的对象封装起来,使得外界不能访问这个属性.上述代码中如果去掉set部分,则外界只能读取name的值,如果去掉get部分,则只能给name赋值.这样就可以控制外界对私有属 ...
- PIL: 建立一个GIF图
PIL: 建立一个GIF图 一.下载PIL库: PIL库的下载是:pip install pillow(pillow就是PIL函数了) 二.采用以下代码(有注释): import PIL.Imag ...
- CSS基础一
css作用 css将内容和样式相分离,便于修改样式.HTML 写网页的内容,CSS写内容的样式 CSS构成 p{ /*p为标签,也可以称为选择器,选择包住的内容的格式*/ font-size:12px ...