一、继承的概念

在现实生活中,继承一般指的是子女继承父辈的财产,在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物;同理,波斯猫和巴厘猫都继承自猫,而沙皮狗和斑点狗都继承足够,如下如所示:

二、继承的示例

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)的更多相关文章

  1. JavaScript高级 面向对象(12)--引用类型值类型作为参数传递的特性

    说明(2017-4-2 18:27:11): 1. 作为函数的参数,就是将函数的数据拷贝一份,传递给函数的定义中的参数. 函数foo()在调用的时候,做了两件事: (1)函数在调用的时候,首先需要将参 ...

  2. python高级-面向对象(11)

    一.面向过程和面向对象 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 二.类和对象 1.类的概念 面向对象编程的 ...

  3. python高级-动态特性(20)

    一.动态语⾔的定义 动态语言是在运行时确定数据类型的语言.变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型.现在比较热门的动态语言有:Python.PHP.JavaScript.Obj ...

  4. Python 高级面向对象

    一.字段 1.字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同. a.普通字段属于对象(实例变量) b.静态字段属于类(类变量) 二.属性 对于属性,有以 ...

  5. 第四篇:python 高级之面向对象初级

    python 高级之面向对象初级   python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 ...

  6. python 高级之面向对象初级

    python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 面向对象:对函数进行分类和封装,让开 ...

  7. Python高级特性(3): Classes和Metaclasses(转)

    原文:Python高级特性(3): Classes和Metaclasses 类和对象 类和函数一样都是Python中的对象.当一个类定义完成之后,Python将创建一个“类对象”并将其赋值给一个同名变 ...

  8. Python高级特性(2):Closures、Decorators和functools(转)

    原文:Python高级特性(2):Closures.Decorators和functools 装饰器(Decorators) 装饰器是这样一种设计模式:如果一个类希望添加其他类的一些功能,而不希望通过 ...

  9. Python高级特性(1):Iterators、Generators和itertools(转)

    译文:Python高级特性(1):Iterators.Generators和itertools [译注]:作为一门动态脚本语言,Python 对编程初学者而言很友好,丰富的第三方库能够给使用者带来很大 ...

随机推荐

  1. oracle数据导出以及导入

    导出 1.服务器上mkdir创建一个真实目录/home/oracle/dump 2.sqlplus /nolog 3.conn /as sysdba; 4.SQL> create directo ...

  2. Python之路(第三十二篇) 网络编程:udp套接字、简单文件传输

    一.UDP套接字 服务端 # udp是无链接的,先启动哪一端都不会报错 # udp没有链接,与tcp相比没有链接循环,只有通讯循环 server = socket.socket(socket.AF_I ...

  3. xtrabackup命令用法实战(转)

    xtrabackup命令用法实战 转载出自 https://blog.csdn.net/wfs1994/article/details/80399408 完全备份 1.创建备份 [root@linux ...

  4. python3 利用pip命令安装包和模块

    本文介绍如何利用pip命令安装Python相关的包和模块.在Python中有些方法或者模块是自带的功能,也叫(build-in),内构函数,实际使用,可能内构函数或者模块不能完成我们的任务,我们就需要 ...

  5. Mac 系统搭建ThinkPHP3.2

    PHP3.2完整包目录 拷贝两个文件 index.php 和ThinkPHP目录到服务器目录中,我已经设置服务器目录与eclipse工作空间为同一个 创建TestThinkPHP 项目 Eclipse ...

  6. 探索微信小程序之路

    记录一下每日的知识点,时不时温习一下. 视图与渲染对于页面中的数据,以json的方式存放在js文件的data中 判断的使用: <view wx:if='{{true}}'> 为真时显示 & ...

  7. 安装php rabbitmq扩展,继上一篇安装Rabbitmq

    1 安装 rabbitmq-c,C 与 RabbitMQ 通信需要依赖这个库,这里只贴出正确的步骤,错误类型太多,不一一举例,大部分都是安装问题,缺少组件,安装目录问题 git clone git:/ ...

  8. C语言的转义字符

    原文地址:http://blog.163.com/sunshine_linting/blog/static/44893323201181325818165/ 在字符集中,有一类字符具有这样的特性:当从 ...

  9. Open/Close Port in Centos

    1. Show status /etc/init.d/iptables status 2.Set Port iptables -I INPUT -p tcp --dport 80 -j ACCEPT ...

  10. JS获取form表单数据

    以下代码可放在一个js文件中,以便通用: //获取指定表单中指定标签对象 function getElements(formId, label) { var form = document.getEl ...