python入门(十三):面向对象(继承、重写、公有、私有)
1、 三种类定义的写法
pass
class P2(): #带(),且括号中为空,类定义
pass
class P3(object): #带括号,且写有object,类定义
pass
p1=P1() #实例化
p2=P2() #实例化
p3=P3() #实例化
print(p1)
print(p2)
print(p3)
运行结果:
E:\>python a.py
<__main__.P1 object at 0x00000219A4A604E0>
<__main__.P2 object at 0x00000219A4A60518>
<__main__.P3 object at 0x00000219A4A60550>
2、类的好处:
可以把数据放在类的实例里面去管理,使用类里面的实例方法来管理这些数据,保证数据的安全性。
def __init__(self,name,age):
if isinstance(age,int) and age >0:
self.age = age
else:
self.age = 0
self.name = name
def set_age(self,age):
if isinstance(age,int) and age >0:
self.age = age
def get_age(self):
return self.age
p1=Person("wulaoshi",18) #实例化
p2=Person("lilaoshi",28) #实例化
p1.age=-100 #可以使用这种p1.age方式,赋值
print(p1.age) #打印实例p1的age为-100
print(p2.age) #打印实例p2中的age为-1
p1.set_age(-10) #试图通过方法set_age更改p1.age的值为-10
print(p1.get_age()) #打印盘p1.age的值
p2.set_age(28) #试图通过方法set_age更改p2.age的值为-10
print(p2.get_age()) #打印盘p2.age的值
运行结果:
E:\>python a.py
18
-100 # p1.age=-100的形式可以赋值成功,可见不安全性
0 #由于实例化时,输入的age值不符合条件,所以
#被强制赋值为0
-100 # 设置年龄-10不满足条件,未设置成功,保留原
28 # p2.set_age(28) 设置成功,数据有变化
def __init__(self,name,age): #该方法表示在实例化的时候会执行
if isinstance(age,int) and age >0: #也就是会在实例化的时候进行判断从而赋值
self.__age = age
else:
self.__age = 0
self.name = name
def set_age(self,age):
if isinstance(age,int) and age >0:
self.__age = age
def get_age(self):
return self.__age
p1=Person("wulaoshi",18)
p2=Person("lilaoshi",-1)
print(p1.__age) #试图在外部访问私有变量
p1.__age=-100 #将变量p1.__age赋值为-100
print(p1.__age) #打印变量p1.__age的值
print(p1.get_age()) #打印真实的实例p1的age
运行结果:
E:\>python a.py
Traceback (most recent call last):
File "a.py", line 19, in <module>
print(p1.__age)
AttributeError: 'Person' object has no attribute '__age' #证明了p1.__age私有变量不可访问
-100 #p1.__age=-100的真实含义是:将-100赋值给了p1.__age这个变量,此时p1.__age并不是实例p1中的age,两者是不同的
18 #查看实例p1中的age,显示还是18.证明了私有变量在外部不可改变,并且p1.__age=-100仅仅是给变量p1.__age赋值而已
1) 内部调用私有方法:
def __init__(self,name,age):
if isinstance(age,int) and age >0:
self.__age = age
else:
self.__age = 0
self.name = name#name是局部变量,self.name是私有变量,局部变量出去这个函数就不能用了,只能在__init__中使用,实例变量在类中的所有方法都能使用这个变量
def set_age(self,age):
if isinstance(age,int) and age >0:
self.__age = age
def __print_age(self): #打印年龄的私有方法
print(self.__age)
def get_age(self):
self.__print_age() #调用私有方法,前面也需要加一个self,私有方法在类的其他的方法中调用
return self.__age
p1=Person("wulaoshi",18)
p2=Person("lilaoshi",28)
p1.get_age()
运行结果:
E:\>python a.py
18 #会打印出年龄,表示私有方法调用成功
2) 外部调用私有方法:
p1.__print_age() #外部调用私有方法
运行结果;
E:\>python a.py
Traceback (most recent call last):
File "a.py", line 23, in <module>
p1.__print_age()
AttributeError: 'Person' object has no attribute '__print_age'
... pass
...
>>> p=P() #实例化
>>> dir(p) #查看类的内置方法
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__form
at__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_s
ubclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclas
shook__', '__weakref__']
前面有__的都是内置方法,有特定的用途
>>> p.__class__
<class '__main__.P'>
>>>
def __init__(self,name):
self.name = name
def get_name(self):#实例方法
print(self.name)
p1=Person("wulaoshi")
p1.get_name()
内存:
类Person放在内存地址:xxxxyyy1
类中的方法get_name():也在这个地址中,并且在调用时要有一个参数self
类变量也在这个地址中
实例p1放在内存地址:mmmmzzz2
这个地址中存有数据name="wulaoshi"
p1.get_name()的调用过程:
1) 在类的地址xxxxyyy1中先把get_name()的内容找出来想去调用
2) 实例变量p1的内存地址--->self=mmmmzzzz2
3) get_name(self=mmmmzzzz2)
4) 执行方法体:print(self.name)
5) 去mmmmzzz2找到name的值,然后打印
总结:
类中的实例方法中的第一个参数self,实际上就是实例所在内存的地址,通过这个地址,可以找到实例方法中需要使用的各种实例属性(数据)。
def __init__(self,name):
self.name = name
def get_name(self):#实例方法
print(self.name)
def get_name2(self):#实例方法
print(self.name,
self.name)
p1=Person("wulaoshi") #mmmmzzzz2
p1.get_name() #self就是p1的内存地址
p1.get_name2() #self就是p1的内存地址
p2=Person("李老师") #mmmmzzzz3
p2.get_name() ##self就是p2的内存地址
p2.get_name2() #self就是p2的内存地址
x=0 #类变量 #类变量,定义在方法外面,没有self;类变量一般用来计数,比如创建了多少个实例
def __init__(self,name): #构造函数只有在实例化的时候才会被执行
self.name = name
Person.x+=1
def get_name(self):#实例方法
print(self.name)
p1=Person("wulaoshi") )#实例化:类名+(参数)
p2=Person("laoli")
p3=Person("laoli")
print(Person.x) #使用类变量时,前面要有类名
print(p1.x) #也可以使用实例名,但是值都是一样的
print(p2.x) #因为类变量在内存中只有一份(类似全局变量),所以不管那个
print(p3.x) #实例变量去访问它,都是一个值
运行结果;
E:\>python a.py
3
3
3
3
8、实例化
类内存:
存类的方法
类变量
"""
实例对象:p2
实例方法:get_name
实例变量:

def __init__(self,name): #当需要向实例中传参数时,便需要写构造函数

p=Person("老王")
print(p.name)
def __init__(self,name):
self.name = name
def set_name(self,name): #父类中有set_name和get_name两个方法
self.name = name
def get_name(self):
return self.name
class AsianPerson(Person): #子类,括号中写入父类名
def __init__(self,name,nation):
Person.__init__(self,name)
self.name = name #通过父类的构造方法的执行,可以生成一个self.name,此句可删
self.nation = nation
def set_nation(self,nation):
self.nation = nation
def get_nation(self):
return self.nation
ap= AsianPerson("laowang","china") #实例化,写进两个参数
print(ap.get_name()) #实例ap中类AsianPerson中并没有get_name()方法
print(ap.get_nation())
ap.set_name("laolaowang") #实例ap中类AsianPerson中并没有set_name()方法
print(ap.get_name())
#但是执行结果均能够正常执行,说明了类的继承实现
p=Person("老李")
print(p.get_name()) #父类Person中,有get_name()方法;#运行正常
3) 调用父类的构造方法:
1) 如果代码中不写Person.__init__(self,name)
class Person:
def __init__(self,name):
self.name = name
def set_name(self,name):
self.name=name
def get_name(self):
return self.name
class AsianPerson(Person):
def __init__(self,name,nation):
self.nation=nation #此处无父类的构造方法,所以未将name做初始化
#所以想使用父类的self.name便失败了
def set_nation(self,nation):
self.nation=nation
def get_nation(self):
return self.nation
ap=AsianPerson("laowang","China")
print(ap.get_name())
运行结果:
E:\>python a.py
Traceback (most recent call last):
File "a.py", line 25, in <module>
print(ap.get_name())
File "a.py", line 10, in get_name
return self.name
AttributeError: 'AsianPerson' object has no attribute 'name'
会提示AsianPerson没有name属性
综上:Person.__init__(self,name)的作用是:
如果想使用父类中的方法和变量的话,则必须在子类的构造函数中,需要调用父类的构造方法,将父类的初始化数据传过去后,父类中的变量和实例方法全部可以被子类使用
父类的私有变量与私有方法不会被继承,父类其他的公有变量和公有方法会被子类所继承
4) 父类中有一个方法是修改自己所有属性的,那么子类调用父类方法就能修改父类的私有属性值:
class Person:
def __init__(self,name):
self.__name = name
def set_name(self,name):
self.__name=name
def get_name(self):
return self.__name
class AsianPerson(Person):
def __init__(self,name,nation):
Person.__init__(self,name)
self.nation=nation
def set_nation(self,nation):
self.nation=nation
def get_nation(self):
return self.nation
ap=AsianPerson("laowang","China")
print(ap.get_name()) #子类调用父类中的私有变量
print(ap.set_name("laoli")) #子类修改父类中的私有变量
print(ap.__name) #在外部方访问私有变量
运行结果:
E:\>python a.py
laowang
None #子类可成功修改父类中的私有变量
Traceback (most recent call last):
File "a.py", line 28, in <module>
print(ap.__name)
AttributeError: 'AsianPerson' object has no attribute '__name' #私有变量不可在外部访问
5)如果父类中有私有变量,那么子类的方法是不能读取父类中的私有变量的
class Person:
def __init__(self):
self.__name = "liuyujing"
def set_name(self,name):
self.__name=name
def get_name(self):
return self.__name
class AsianPerson(Person):
def __init__(self,name,nation):
Person.__init__(self)
self.nation=nation
def get_name(self):
return self.__name #子类中的方法不能访问父类中的私有变量
ap=AsianPerson("laowang","China")
print(ap.get_name())
运行结果:
E:\>python a.py
Traceback (most recent call last):
File "a.py", line 23, in <module>
print(ap.get_name())
File "a.py", line 20, in get_name
return self.__name
AttributeError: 'AsianPerson' object has no attribute '_AsianPerson__name'
def __init__(self,name):
self.name = name
def set_name(self,name):
self.name = name
def get_name(self):
return self.name
class AsianPerson(Person):
def __init__(self,name,nation):
Person.__init__(self,name)
self.nation = nation
def get_name(self):#重写了父类中的方法
return "****:"+self.name
ap= AsianPerson("laowang","china")
print(ap.get_name()) #在调用时调用的是子类的get_name()方法,将父类的方法覆盖掉了
子类中重写了父类的方法,如果使用父类创建实例对象时,调用的还是父类里的方法。
重写:把父类的方法覆盖掉,使用子类的同名方法
重载; 多个方法名一样,但是他们的参数类型,还有参数个数不一样(相对java说的),python不支持重载
11、 明确调用父类中的方法
1) super().get_name()方式调用父类中的方法
class Person:
def __init__(self,name):
self.name = name
def set_name(self,name):
self.name=name
def get_name(self):
return self.name
class AsianPerson(Person):
def __init__(self,names,nation):
Person.__init__(self,name)
self.nation=nation
def set_nation(self,nation):
self.nation=nation
def get_nation(self):
return self.nation
def get_name(self):
return "***:"+super().get_name()#调用父类中的get_name()方法,super是关键字
ap=AsianPerson("laowang","China")
print(ap.get_name())
运行结果;
E:\>python a.py
***:laowang
2) Person.get_name(self)方式调用父类中的方法
class Person:
def __init__(self,name):
self.name = name
def set_name(self,name):
self.name=name
def get_name(self):
return self.name
class AsianPerson(Person):
def __init__(self,name,nation):
Person.__init__(self,name)
self.nation=nation
def set_nation(self,nation):
self.nation=nation
def get_nation(self):
return self.nation
def get_name(self):
return "***:"+Person.get_name(self) #括号内需要写self
ap=AsianPerson("laowang","China")
print(ap.get_name())
运行结果:
E:\>python a.py
***:laowang
3) super(AsianPerson,self).get_nam方式调用父类中的方法
class Person:
def __init__(self,name):
self.name = name
def set_name(self,name):
self.name=name
def get_name(self):
return self.name
class AsianPerson(Person):
def __init__(self,name,nation):
Person.__init__(self,name)
self.nation=nation
def set_nation(self,nation):
self.nation=nation
def get_nation(self):
return self.nation
def get_name(self):
return "***:"+super(AsianPerson,self).get_name()
ap=AsianPerson("laowang","China")
print(ap.get_name())
运行结果:
E:\>python a.py
***:laowang
python入门(十三):面向对象(继承、重写、公有、私有)的更多相关文章
- Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态)
Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态) 1.面向对象的三大特性: (1)继承 继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可以 ...
- Python进阶(十三)----面向对象
Python进阶(十三)----面向对象 一丶面向过程编程vs函数式编程vs面向对象编程 面向过程: 简而言之,step by step 一步一步完成功能,就是分析出解决问题所需要的步骤,然后用函 ...
- Python入门篇-面向对象概述
Python入门篇-面向对象概述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.语言的分类 面向机器 抽象成机器指令,机器容易理解 代表:汇编语言 面向过程 做一件事情,排出个 ...
- Python入门之面向对象的__init__和__new__方法
Python入门之面向对象的__init__和__new__方法
- 【学习笔记】--- 老男孩学Python,day18 面向对象------继承
继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类, 父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 class Fathe ...
- Python入门之面向对象的多态和继承
本章内容 Python面向对象的多态和继承对比 ========================================= 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的 ...
- Python入门之面向对象之类继承与派生
本章内容 一.继承 二.抽象类 三.继承的实现原理 ======================================================= 一.继承 1. 继承的定义 继承是一 ...
- Python之路-面向对象&继承和多态&类属性和实例属性&类方法和静态方法
一.面向对象 编程方式 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强…” 什么是面 ...
- Python入门之面向对象编程(四)Python描述器详解
本文分为如下部分 引言——用@property批量使用的例子来引出描述器的功能 描述器的基本理论及简单实例 描述器的调用机制 描述器的细节 实例方法.静态方法和类方法的描述器原理 property装饰 ...
- Python入门-初始面向对象
之前我们代码基本上都是面向过程的,今天我们就来初始一下python中一个重要的内容:面向对象 一.面向对象和面向过程(重点理解) 1.面向过程: 一切以事物的流程为核心. 核心是"过程&qu ...
随机推荐
- 关于DDS的基础知识
关于DDS的基础知识 声明:这篇博客是我抄别人的,为什么想抄呢,因为他把DDS中的核心部件,相位累加器以及正弦ROM查找表寻址讲得明明白白,我真的好想把这篇文章据为己有. DDS是直接数字式频率合成器 ...
- 13行代码实现:Python实时视频采集(附源码)
一.前言 本文是<人脸识别完整项目实战>系列博文第3部分:程序设计篇(Python版),第1节<Python实时视频采集程序设计>,本章内容系统介绍:基于Python+open ...
- Asynchronous programming in javascript
Javascript是单线程的,因此异步编程对其尤为重要. ES 6以前: * 回调函数* 事件监听(事件发布/订阅)* Promise对象 ES 6: * Generator函数(协程corouti ...
- 联想T470笔记本GPT改MBR分区
联想T470笔记本GPT改MBR分区 7000多元买的,这个笔记本配置还可以,就是感觉特别卡顿,于是想重做WIN7系统,为了方便激活,想把GPT分区改成MBR分区. 进入微PE1.2,用傲梅分区助手删 ...
- Azkaban 使用问题及解决(一)
什么是Azkaban Azkaban是一款基于Java编写的任务调度系统 任务调度:有四个任务脚A.B.C.D,其中任务A与任务B可以并行运行,然后任务C依赖任务A和任务B的运行结果,任务D依赖任务C ...
- 激活WINDOWS SERVER 2019
Windows Server 2019 Datacenter WMDGN-G9PQG-XVVXX-R3X43-63DFGWindows Server 2019 Standard N69G4-B89J2 ...
- Halcon Visinpro 破解版
目前测试过的破解版资料: halcon10 可用已测 完美破解 halcon12 可用已测 完美破解 halcon13 可用已测 完美破解 halcon17 可用已测 ...
- 音乐出身的妹纸,零基础学习JAVA靠谱么
问:表示音乐出身的妹纸一枚 某一天突然觉得身边认识的是一群程序员 突然想 要不要也去试试... 众好友都觉得我该去做个老师,可是我怕我会误人子弟,祸害祖国下一代..... 要不要 要不要 学Ja ...
- windows计划任务启动bat执行java文件
系统:win7 环境:需要配置好jdk的环境变量 需求:每次开机,用bat批处理执行将一个位于D:\workspace\console目录底下的console.txt重命名的java文件 拿到需求,我 ...
- 用JavaScript制作页面特效
1.Window对象 名称 history:有关客户访问过的URL的信息 location:有关当前URL的信息 screen:有关客户端的屏幕和显示性能的信息 常用方法 prompt():弹出输入框 ...