一、继承的概念

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

二、继承的示例

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. java8 先groupingBy 后map

    Map<Integer,List<String>> mapBanJI_UserNameList=list.stream().collect(Collectors.groupin ...

  2. 从mysql主从复制到微信开源的phxsql

    严格的来说,微信开源的phxsql不是数据库,而是一个数据库的插件: 传统的互联网数据库结构一般是这样的: 服务访问数据库是通过分片来的: 除了这种基于hash的分片,还有一种基于range的分片方式 ...

  3. jquery datatables+MVC+WCF

    view @{ Layout = null;} <!DOCTYPE html><html><head> <title>111</title> ...

  4. ABP 依赖注入

    1.ABP自动注入 //IapplicationService注入方式暴露接 //ITransientDependency 不会暴露接口 ITransientDependency和ISingleton ...

  5. C#下载Url文件到本地

    protected void Page_Load(object sender, EventArgs e) { string filePath = Request.Params["FilePa ...

  6. SpringCloud(一)Eureka注册中心

    Eureka简介 Eureka作为注册中心,管理各种服务功能包括服务的注册.发现.熔断.负载.降级等 Eureka注册中心实例 Eureka Server 1.pom文件配置SpringBoot.Sp ...

  7. C++ vector动态数组

    #include<vector>头文件 vector类称作向量类 百度百科的解释:https://baike.baidu.com/item/vector/3330482 我喜欢把知识点拿出 ...

  8. list对象中根据两个参数过滤数据

    list对象中根据两个参数过滤数据 List<demo> list = new List<demo>() { ,b=,c=,d= }, ,b=,c=,d= }, ,b=,c=, ...

  9. 《Linux就该这么学》第十天课程

    使用RAID与LVM磁盘阵列技术 有RAID 0,RAID 1,,RAID 5,RAID 1 0等,下面列举RAID的各个概况 1. RAID 0 RAID 0技术把多块物理硬盘设备(至少两块)通过硬 ...

  10. Appium系列文章(1)获取appPackage和appActivity

    appPackage和appActivity 进行appium自动化测试非常重要的两个参数,我们所测试的APP不同,这两个参数肯定也是不一样的.那如何快速的获取这APP的这两个参数呢? 通过cmd命令 ...