python----类,面向对象(封装、继承、多态)(属性,方法)
什么是对象?
- 对象是内存中专门用来存储数据的一块区域
- 对象中可以存放各种数据(数字、代码等)
- 对象由三部分组成(1,对象标识(id)2,对象类型(type)3,对象的值(value))
面向对象编程是最有效的编写方法之一;在面向对象编程中,编写表现和实现世界中的事物和情景的类,并根据这些"类"来创造"对象";使用"类"几乎可以模仿任何东西。
面向对象的三大特性:
- 封装:顾名思义将属性和方法封装到一个抽象的类当中,创建对象时再去调用;
- 继承:面向对象中的继承就是继承的类直接拥有被继承类的属性而不需要在自己的类体中重新再写一遍;继承实现代码的重用,相同的代码不需要重复的编写;
- 多态:多态就是不同的对象可以调用相同的方法然后得到不同的结果,(在python中处处体现着多态,比如不管你是列表还是字符串还是数字都可以使用+和*)
类的定义
所有的事物由两部分组成
- 数据(属性)
- 方法(动作)---(定义在类中的函数)
创建Dog类
创建的Dog类 有属性 有方法
- 属性:年龄(age) 名字(name)
- 动作:跑 叫
规定:定义类函数需用驼峰命名法(首字母大写)
class Dog(object):
def __init__(self,name,age): #初始化属性name和age
self.name = name
self.age = age
def run(self): #定义跑动作
print('%s is running.......' % self.name)
def bark(self): #定义叫的动作
print('%s is barking............' % self.name)
def __str__(self): #可以设定返回值
return 'dog_name %s \ndog_age %s岁' %(self.name,self.age)
wangcai = Dog('wangcai',2)
print(wangcai)
wangcai.run()
wangcai.bark()
.......................................................运行结果
#Dog为类,wancai是根据Dog类实例出来的一个对象;
dog_name wangcai
dog_age 2岁
wangcai is running.......
wangcai is barking............
类交叉
士兵突击
- 士兵许三多有一把AK47
- 士兵可以开火
- 枪能发射子弹
- 枪能装填子弹
class Gun(object):
def __init__(self,model):
self.model = model
self.count = 0
def add_bullet(self,count):
self.count+=count
def shoot(self):
if self.count >= 3:
self.count-=3
print('tututu>>>\n枪里还有%s发子弹'%self.count)
else:
print('没有子弹了!!!')
class Soldier(object):
def __init__(self,name):
self.name = name
self.gun = None
def fire(self):
if self.gun:
self.gun.shoot()
print('%s冲啊!!!'%self.name)
else:
print('没枪!没枪!')
def add(self):
self.gun.add_bullet(30)
def __str__(self): #__str__ 魔术方法return加print两个功能
return '士兵:%s 好同志!!!'%self.name
ak47 = Gun('AK47')
xusanduo = Soldier('xusanduo')
# xusanduo.fire()
xusanduo.gun = ak47
xusanduo.add()
xusanduo.fire()
................................运行结果
tututu>>>
枪里还有27发子弹
xusanduo冲啊!!!
封装
封装是面向对象的三大特性之一
封装指的是隐藏对象中一些不希望被外部所访问到的属性或方法
如何隐藏一个对象中的属性?
- 将对象的属性名,修改为一个外部不知道的名字
如何获取(修改)对象中的属性?
- 需要提供一个getter和setter方法使外部可以访问到属性
- getter 获取对象中的指定属性(get_属性名)
- setter 用来设置对象的指定属性(set_属性名)
使用封装,确实增加了类的定义的复杂程度,但是它也确保了数据的安全性
1.隐藏了属性名,使调用者无法随意的修改对象中的属性
2.增加了getter和setter方法,很好的控制的属性是否是只读的
如果希望属性是只读的,则可以直接去掉setter方法
如果希望属性不能被外部访问,则可以直接去掉getter方法
3.使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的
4.使用getter方法获取属性,使用setter方法设置属性
可以在读取属性和修改属性的同时做一些其他的处理
5.使用getter方法可以表示一些计算的属性
class Dog:
'''
表示狗的类
'''
def __init__(self , name , age):
self.hidden_name = name
self.hidden_age = age
def say_hello(self):
print('大家好,我是 %s'%self.hidden_name)
def get_name(self):
'''
get_name()用来获取对象的name属性
'''
# print('用户读取了属性')
return self.hidden_name
def set_name(self , name):
# print('用户修改了属性')
self.hidden_name = name
def get_age(self):
return self.hidden_age
def set_age(self , age):
if age > 0 :
self.hidden_age = age
d = Dog('旺财',8)
# d.say_hello()
# 调用setter来修改name属性
d.set_name('小黑')
d.set_age(-10)
# d.say_hello()
print(d.get_age())
隐藏属性
# 双下划线开头的属性,是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过对象访问
# 其实隐藏属性只不过是Python自动为属性改了一个名字
# 实际上是将名字修改为了,_类名__属性名 比如 __name -> _Person__name
# class Person:
# def __init__(self,name):
# self.__name = name
# def get_name(self):
# return self.__name
# def set_name(self , name):
# self.__name = name
# p = Person('孙悟空')
# print(p.__name) __开头的属性是隐藏属性,无法通过对象访问
# p.__name = '猪八戒'
# print(p._Person__name)
# p._Person__name = '猪八戒'
# print(p.get_name())
# 使用__开头的属性,实际上依然可以在外部访问,所以这种方式我们一般不用
# 一般我们会将一些私有属性(不希望被外部访问的属性)以_开头
# 一般情况下,使用_开头的属性都是私有属性,没有特殊需要不要修改私有属性
class Person:
def __init__(self,name):
self._name = name
def get_name(self):
return self._name
def set_name(self , name):
self._name = name
p = Person('孙悟空')
print(p._name)
setter方法和getter方法的装饰器
class Person:
def __init__(self,name,age):
self._name = name
self._age = age
# property装饰器,用来将一个get方法,转换为对象的属性
# 添加为property装饰器以后,我们就可以像调用属性一样使用get方法
# 使用property装饰的方法,必须和属性名是一样的
@property
def name(self):
print('get方法执行了~~~')
return self._name
# setter方法的装饰器:@属性名.setter
# setter方法的装饰器使用的前提要有property装饰器,因为必须要可以调用才可以更改
@name.setter
def name(self , name):
print('setter方法调用了')
self._name = name
@property
def age(self):
return self._age
@age.setter
def age(self , age):
self._age = age
p = Person('猪八戒',18)
p.name = '孙悟空'
p.age = 28
print(p.name,p.age)
继承
编写类时,并非总要从空白开始,如果你要编写的类是另一个类的特殊版本,可使用继承。一个类继承另一个类时他将自动获得父类的所有属性和动作,同时还可以有自己的属性和方法,发生冲突时以自己为准。
检查方法
# issubclass() 检查一个类是否是另一个类的子类
# print(issubclass(Animal , Dog))
# print(issubclass(Animal , object))
# print(issubclass(Person , object))
# isinstance()用来检查一个对象是否是一个类的实例
# 如果这个类是这个对象的父类,也会返回True
# 所有的对象都是object的实例
print(isinstance(print , object))
实例:
class Dog(object):
def __init__(self,name,age): #初始化属性name和age
self.name = name
self.age = age
def run(self): #定义跑动作
print('%s is running.......' % self.name)
def bark(self): #定义叫的动作
print('%s is barking............' % self.name)
def __str__(self): #__str__魔术方法,可以设定返回值
return 'dog_name %s \ndog_age %s岁' %(self.name,self.age)
class XiaoTianQuan(Dog):
def bark(self):
print('%s barking >>>>>>>>>>' % self.name)
def fly(self):
print("%s is flying.........."% self.name)
feitianwangcai = XiaoTianQuan('feitianwangcai',500)
print(feitianwangcai)
feitianwangcai.bark()
feitianwangcai.fly()
..........................................运行结果
dog_name feitianwangcai
dog_age 500岁
feitianwangcai barking >>>>>>>>>>
feitianwangcai is flying..........
使用super()继承父类属性
class Animal:
def __init__(self,name):
self._name = name
def run(self):
print('动物会跑~~~')
def sleep(self):
print('动物睡觉~~~')
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
# 父类中的所有方法都会被子类继承,包括特殊方法,也可以重写特殊方法
# 当我们需要继承父类中__init__属性时,还有需求添加一些属性
class Dog(Animal):
def __init__(self,name,age):
# 希望可以直接调用父类的__init__来初始化父类中定义的属性
# Animal.__init__(self,name) #可以继承父类的__init__属性,
# 但是此方法耦合性比较高,super() 可以用来获取当前类的父类,
# 并且通过super()返回对象调用父类方法时,不需要传递self
super().__init__(name)
self._age = age
def bark(self):
print('汪汪汪~~~')
def run(self):
print('狗跑~~~~')
@property
def age(self):
return self._age
@age.setter
def age(self,age):
self._age = name
d = Dog('旺财',18)
print(d.name)
print(d.age)
多继承
- 编写类时,可以继承多个父类的属性和动作,发生冲突时以前面的亲爹为主
- 多重继承,会使子类同时拥有多个父类,并且会获取到所有父类中的方法
- 在开发中没有特殊的情况,应该尽量避免使用多重继承,因为多重继承会让我们的代码过于复杂
- 如果多个父类中有同名的方法,则会现在第一个父类中寻找,然后找第二个,然后找第三个。。。
- 前边父类的方法会覆盖后边父类的方法
实例:
class Dog(object):
def __init__(self,name,age): #初始化属性name和age
self.name = name
self.age = age
def run(self): #定义跑动作
print('%s is running.......' % self.name)
def bark(self): #定义叫的动作
print('%s is barking............' % self.name)
def __str__(self): #可以设定返回值
return 'dog_name %s \ndog_age %s岁' %(self.name,self.age)
class Humen(object):
def __init__(self,name,age,power):
self.name = name
self.age = age
self.power = power
def talk(self):
print('I can talking!!')
def __str__(self):
return 'name %s \nage %s岁 \n战力值:%s' % (self.name, self.age, self.power)
class XiaoTianQuan(Humen,Dog): #大家可以尝试着换下位置
def fly(self):
print("%s is flying.........."% self.name)
feitianwangcai = XiaoTianQuan('feitianwangcai',500,10000)
print(feitianwangcai)
feitianwangcai.bark()
feitianwangcai.fly()
feitianwangcai.talk()
........................................................运行结果
name feitianwangcai
age 500岁
战力值:10000
feitianwangcai is barking............
feitianwangcai is flying..........
I can talking!!
类中的属性和方法
# 定义一个类
class A(object):
# 类属性
# 实例属性
# 类方法
# 实例方法
# 静态方法
# 类属性,直接在类中定义的属性是类属性
# 类属性可以通过类或类的实例访问到
# 但是类属性只能通过类对象来修改,无法通过实例对象修改
count = 0
def __init__(self):
# 实例属性,通过实例对象添加的属性属于实例属性
# 实例属性只能通过实例对象来访问和修改,类对象无法访问修改
self.name = '孙悟空'
# 实例方法
# 在类中定义,以self为第一个参数的方法都是实例方法
# 实例方法在调用时,Python会将调用对象作为self传入
# 实例方法可以通过实例和类去调用
# 当通过实例调用时,会自动将当前调用对象作为self传入
# 当通过类调用时,不会自动传递self,此时我们必须手动传递self
def test(self):
print('这是test方法~~~ ' , self)
# 类方法
# 在类内部使用 @classmethod 来修饰的方法属于类方法
# 类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象
# 类方法和实例方法的区别,实例方法的第一个参数是self,而类方法的第一个参数是cls
# 类方法可以通过类去调用,也可以通过实例调用,没有区别
@classmethod
def test_2(cls):
print('这是test_2方法,他是一个类方法~~~ ',cls)
print(cls.count)
# 静态方法
# 在类中使用 @staticmethod 来修饰的方法属于静态方法
# 静态方法不需要指定任何的默认参数,静态方法可以通过类和实例去调用
# 静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数
# 静态方法一般都是一些工具方法,和当前类无关
@staticmethod
def test_3():
print('test_3执行了~~~')
a = A()
# 实例属性,通过实例对象添加的属性属于实例属性
# a.count = 10
# A.count = 100
# print('A ,',A.count)
# print('a ,',a.count)
# print('A ,',A.name)
# print('a ,',a.name)
# a.test() 等价于 A.test(a)
# A.test_2() 等价于 a.test_2()
A.test_3()
a.test_3()
特殊方法
官网:https://docs.python.org/3/reference/datamodel.html
# 特殊方法,也称为魔术方法
# 特殊方法都是使用__开头和结尾的
# 特殊方法一般不需要我们手动调用,需要在一些特殊情况下自动执行
# 定义一个Person类
class Person(object):
"""人类"""
def __init__(self, name , age):
self.name = name
self.age = age
# __str__()这个特殊方法会在尝试将对象转换为字符串的时候调用
# 它的作用可以用来指定对象转换为字符串的结果 (print函数)
def __str__(self):
return 'Person [name=%s , age=%d]'%(self.name,self.age)
# __repr__()这个特殊方法会在对当前对象使用repr()函数时调用
# 它的作用是指定对象在 ‘交互模式’中直接输出的效果
def __repr__(self):
return 'Hello'
# object.__add__(self, other)
# object.__sub__(self, other)
# object.__mul__(self, other)
# object.__matmul__(self, other)
# object.__truediv__(self, other)
# object.__floordiv__(self, other)
# object.__mod__(self, other)
# object.__divmod__(self, other)
# object.__pow__(self, other[, modulo])
# object.__lshift__(self, other)
# object.__rshift__(self, other)
# object.__and__(self, other)
# object.__xor__(self, other)
# object.__or__(self, other)
# object.__lt__(self, other) 小于 <
# object.__le__(self, other) 小于等于 <=
# object.__eq__(self, other) 等于 ==
# object.__ne__(self, other) 不等于 !=
# object.__gt__(self, other) 大于 >
# object.__ge__(self, other) 大于等于 >=
# __len__()获取对象的长度
# object.__bool__(self)
# 可以通过bool来指定对象转换为布尔值的情况
def __bool__(self):
return self.age > 17
# __gt__会在对象做大于比较的时候调用,该方法的返回值将会作为比较的结果
# 他需要两个参数,一个self表示当前对象,other表示和当前对象比较的对象
# self > other
def __gt__(self , other):
return self.age > other.age
# 创建两个Person类的实例
p1 = Person('孙悟空',18)
p2 = Person('猪八戒',28)
# 打印p1
# 当我们打印一个对象时,实际上打印的是对象的中特殊方法 __str__()的返回值
# print(p1) # <__main__.Person object at 0x04E95090>
# print(p1)
# print(p2)
# print(repr(p1))
# t = 1,2,3
# print(t) # (1, 2, 3)
# print(p1 > p2)
# print(p2 > p1)
# print(bool(p1))
# if p1 :
# print(p1.name,'已经成年了')
# else :
# print(p1.name,'还未成年了')
python----类,面向对象(封装、继承、多态)(属性,方法)的更多相关文章
- php面向对象 封装继承多态 接口、重载、抽象类、最终类总结
1.面向对象 封装继承多态 接口.重载.抽象类.最终类 面向对象 封装继承多态 首先,在解释面向对象之前先解释下什么是面向对象? [面向对象]1.什么是类? 具有相同属性(特征)和方法(行为)的一 ...
- python面向对象(封装,继承,多态)
python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...
- Java基础——面向对象(封装——继承——多态 )
对象 对象: 是类的实例(实现世界中 真 实存在的一切事物 可以称为对象) 类: 类是对象的抽象描述 步骤: 1.定义一个类 (用于 描述人:) ( * 人:有特征和行为) 2.根据类 创建对象 -- ...
- Python设计模式 - 基础 - 封装 & 继承 & 多态
面向对象的核心是对象,世间万物都可以看作对象,任何一个对象都可以通过一系列属性和行为来描述,可以包含任意数量和类型的数据或操作.类是用来描述具有相同属性和方法的所有对象的集合.类通常是抽象化的概念,而 ...
- java类的封装 继承 多态
1.猜数字小游戏 package cn.jiemoxiaodi_02; import java.util.Scanner; /** * 猜数字小游戏 * * @author huli * */ pub ...
- Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态)
Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态) 1.面向对象的三大特性: (1)继承 继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可以 ...
- java面向对象(封装-继承-多态)
框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...
- python类的封装与继承
封装 关注公众号"轻松学编程"了解更多. 1.概念 面向对象语言的三大特征:封装, 继承, 多态. 广义的封装: 类和函数的定义本身就是封装的体现. 狭义的封装:一个类的某些属性, ...
- Python之面向对象封装
Python之面向对象封装 封装不是单纯意义的隐藏 什么是封装: 将数据放在一个设定好的盒子里,并标出数据可以实现的功能,将功能按钮外露,而隐藏其功能的工作原理,就是封装. 要怎么封装: 你余额宝有多 ...
- 浅谈学习C++时用到的【封装继承多态】三个概念
封装继承多态这三个概念不是C++特有的,而是所有OOP具有的特性. 由于C++语言支持这三个特性,所以学习C++时不可避免的要理解这些概念. 而在大部分C++教材中这些概念是作为铺垫,接下来就花大部分 ...
随机推荐
- 第三章 存储器的扩展(二)——> 重要
3.2 主存储器 四.只读存储器(ROM)---->了解(考试也可能会考) 掩膜ROM(MROM) 行列选择线交叉处有 MOS 管为"1" 行列选择线交叉处无 MOS 管为& ...
- sql操作数据库(3)-->外键约束、数据库表之间的关系、三大范式、多表查询、事务
外键约束 在新表中添加外键约束语法: constraint 外键约束名称 foreign key(外键的字段名称) references 主表表名(主键字段名) 在已有表中添加外键约束:alter t ...
- ES6 class类 静态方法及类的继承
一.class类 ES6之前都是定义函数以及函数的原型对象实现类型, 如果想要实现共享构造函数成员,可以用prototype来共享实现 ES6出现之后,使用class类的概念来实现原型的继承 二,静态 ...
- linuix查端口
根据进程pid查端口:netstat -nap | grep pid 根据端口port查进程:netstat -nap | grep port 根据pid查找文件的启动位置 ps aux | gre ...
- Sentry(v20.12.1) K8S 云原生架构探索,玩转前/后端监控与事件日志大数据分析,高性能+高可用+可扩展+可伸缩集群部署
Sentry 算是目前开源界集错误监控,日志打点上报,事件数据实时分析最好用的软件了,没有之一.将它部署到 Kubernetes,再搭配它本身自带的利用 Clickhouse (大数据实时分析引擎)构 ...
- 项目实战--JSON.toJSONString()
需求说明:公司使用Swagger(接口文档在线生成工具),为了让前端同事更好的了解传入参数的详细情况,应用项目中接口(eg:分页查询接口)中使用dto对象来接受前端传入的参数,但是后面中心项目中接口是 ...
- swoole中websoket创建在线聊天室(php)
swoole中websoket创建在线聊天室(php) swoole现仅支持Linix,macos 创建websocket服务器 首先现在服务器创建一个websocket服务器 <?php // ...
- springboot 和 mongdb连接问题 Exception in thread "main" com.mongodb.MongoSecurityException:
1 Exception in thread "main" com.mongodb.MongoSecurityException: Exception authenticating ...
- mysql的安全问题
mysql 用户目录下,除了数据文件目录,其他文件和目录属主都改为root 删除空账号 drop user ''@'localhost'; 给root 设置口令 在[client]中写入user='' ...
- 【ORA】ORA-27125:unable to create shared memory segment
在安装Oracle 10g的时候出现一个了错误,在网上总结了一下大牛写的文章 ORA-27125:unable to create shared memory segment 安装时出现这个错误安装会 ...