Python9--面向对象编程
1. 面向对象编程简介
面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。它可能包含数据、属性、代码与方法。对象则指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象(引自维基百科)
2.面向对象4个核心概念
- 抽象
- 封装
- 继承
- 多态
3.类的定义
- 类和对象
面向对象
的两个基本概念类
和实例
,而实例
是根据类创建出来的一个个具体的“对象”
,一个类中既会定义属性
,也会定义方法
- 类的命名规则遵循
大驼峰命名法
:每个单词的第一个字母都大写,私有类使用下划线
开头
class ClassName:
<statement-1>
.
.
.
<statement-N>
- 下面定义一个
People
的类,并且实例化为student
>>> class People():
... pass
...
>>> student = People()
>>> print(student)
<__main__.People object at 0x10e1796d0>
>>> People()
<__main__.People object at 0x10e179750>
>>> People
<class '__main__.People'>
>>> student.name = 'yiluo'
>>> student.name
'yiluo'
-
0x10e1796d0
为内存地址 -
实例方法
在Python
中只要新建一个类就会自动创建它的内置类方法
或属性
,可以通过dir(类名)
查看
>>> class People():
... pass
...
>>> dir(People)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
- 其中最常用的是
__init__
方法,它可以对实例进行初始化设置
(类的内置方法
前后各有两个下划线_
,简称:“双下划线
”) - 下面重新写一个类并初始化名字
(yiluo) ➜ Code touch people.py
(yiluo) ➜ Code vim people.py
#!/usr/bin/python3
class People():
def __init__(self):
self.name = 'yiluo'
student = People()
print(student.name)
- 执行文件打印出了名字
(yiluo) ➜ Code python people.py
yiluo
- 类中的函数通常称作方法,
self
所指的是就是实例本身,下面修改下类中的属性,也就是年龄
# 作者:伊洛Yiluo 公众号:伊洛的小屋
# 个人主页:https://yiluotalk.com/
# 博客园:https://www.cnblogs.com/yiluotalk/
#!/usr/bin/python3
class People():
def __init__(self, name):
self.name = name
self.age = '20'
student = People('yiluo')
print(student.name)
student.age = '18'
print(student.age)
- 年龄被修改为了18岁
(yiluo) ➜ Code python people.py
yiluo
18
-
__repr__
来格式化实例的打印格式
#!/usr/bin/python3
class People():
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return 'Student: {}'.format(self.name)
student = People('yiluo', 20)
print(student.name)
print(student.age)
print(student)
- 格式化打印输出
(yiluo) ➜ Code python people.py
yiluo
20
Student:yiluo
4.类的封装
在面向对象
的语言中,封装
就是用类将数据
和基于数据
的操作封装在一起,隐藏内部数据
,对外提供公共的访问
#!/usr/bin/python3
class People():
def __init__(self, name, age):
self._name = name
self._age = age
def get_name(self):
return self._name
def get_age(self):
return self._age
def set_name(self, name):
self._name = name
def set_age(self, age):
self._age = age
def score(self, score):
print('姓名:{}'.format(self.get_name()) + ' '+ '年龄:{}'.format(self.get_age())+ ' ' + '得分:{}'.format(score) )
# 创建实例对象student
student = People('yiluo', '20')
student.get_name()
student.get_age()
student.score('98')
#重新设置名字和年龄
student.set_name('luoyi')
student.set_age('19')
#重新获得名字和年龄
student.get_name()
student.get_age()
student.score('99')
- Python 的
私有属性
用一个或两个下划线开头表示,一个下划线表示外部调用者不应该直接调用这个属性
,但其实还是可以调用的; 如果是两个下划线
就不能调用 - 执行一下,看下结果
(yiluo) ➜ Code python people.py
姓名:yiluo 年龄:20 得分:98
姓名:luoyi 年龄:19 得分:99
5.类的继承与方法重写
- 继承分为两种:
单继承
和多继承
。单继承
是指子类只继承于一个父类,相应的多继承
是指子类继承于多个父类 -
单继承
与方法重写
#!/usr/bin/python3
class People(object):
def __init__(self, name, age):
self._name = name
self._age = age
def get_name(self):
return self._name
def get_age(self):
return self._age
def set_name(self, name):
self._name = name
def set_age(self, age):
self._age = age
def title(self):
pass
class Student(People):
def title(self):
print('姓名{}'.format(self.get_name()) + ' ' + '年龄{}'.format(self.get_age()) + ' ' + '职业:学生')
class Teacher(People):
def title(self):
print('姓名{}'.format(self.get_name()) + ' ' + '年龄{}'.format(self.get_age()) + ' ' + '职业:教师')
student = Student('yiluo', '20')
teacher = Teacher('luoyi', '19')
student.title()
(yiluo) ➜ Code python people.py
姓名yiluo 年龄20 职业:学生
姓名luoyi 年龄19 职业:教师
- 所谓重写父类的方法就是指:在子类中定义和父类同名的方法,那么子类中的该方法就会覆盖掉父类中对应的方法
6.类的多继承
# 作者:伊洛Yiluo 公众号:伊洛的小屋
# 个人主页:https://yiluotalk.com/
# 博客园:https://www.cnblogs.com/yiluotalk/
class Name():
def __init__(self):
self.name = 'yiluo'
def demo1(self):
print('打印名字')
class Age():
def __init__(self):
self.age = 20
def demo2(self):
print('打印年龄')
class Somebody(Name, Age):
def __init__(self):
Name.__init__(self)
Age.__init__(self)
def demo3(self):
print('打印某人')
somebody = Somebody()
print(somebody.name)
print(somebody.age)
somebody.demo1()
somebody.demo2()
somebody.demo3()
yiluo) ➜ Code python demo.py
yiluo
20
打印名字
打印年龄
打印某人
7.多态
多态就是使用同一方法对不同对象可以产生不同的结果
8.私有属性和方法
-
Python
在属性方法名前添加__
(两个下划线 __
)来拒绝外部的访问 - 两个下划线是设置私有
属性/方法
的标准样式, 还有一种设置私有属性/方法
的样式,就是在属性/方法
名字前加一个下划线_
但是其实这样的私有属性/方法
只仅仅是视为不能直接访问,但是实际上还是可以访问的
如果你觉得文章对你有些帮助,欢迎微信搜索「伊洛的小屋」第一时间阅读
9.类属性,类方法
类属性
和类方法
是可以直接使用类访问,不需要实例化
- 类属性
>>> class Hero(object):
... skill = 'fire'
... def __init__(self, name):
... self._name = name
...
>>> Hero.skill
'fire'
>>> xiangyu= Hero('项羽')
>>> xiangyu.skill
'fire'
1.创建一个英雄类
2.英雄的技能是火焰
3.初始化英雄的名字
4.实例一个英雄
5.调用英雄的技能属性
- 类方法
类方法用装饰器@classmethod
装饰,类方法中可以访问类属性
类方法的第一个参数传入的是类对象,而不是实例对象
,约定俗成的,类方法
中要指代类对象本身都使用cls
>>> class Hero(object):
... skill = 'fire'
... def __init__(self, name):
... self._name = name
... @classmethod
... def get_skill(cls):
... return cls.skill
...
>>> Hero.get_skill()
'fire'
>>> liubei = Hero('刘备')
>>> liubei._name
'刘备'
>>> liubei.get_skill()
'fire'
1.不需要实例化就可以调用
- 静态方法
静态方法用装饰器@staticmethod
装饰,和@classmethod
有点类似。静态方法在运行时不需要实例的参与,并且也不需要传递cls
#!/usr/bin/python3
class Hero(object):
skill = 'fire'
def __init__(self, name):
self._name = name
@staticmethod
def release_skills():
print(guanyu._name + ' ' +'释放技能' + ': '+ Hero.skill)
guanyu = Hero('关羽')
Hero.release_skills()
1.静态方法 ,英雄释放技能
2.不需要实例化直接释放火焰技能
(yiluo) ➜ Code python test.py
关羽 释放技能: fire
10.property 装饰器
@property
装饰器可以将一个方法
变成一个属性
来使用,通过 @property
装饰器可以获得和修改对象的某一个属性
@property 表示只读
@property 和 @.setter 表示可读可写
@property、@.setter、和 @.deleter 表示可读可写可删除
@property 必须定义在 @.setter 的前面
类必须继承 object 父类,否则 @property 不会生效
#!/usr/bin/python3
class Hero(object):
skill = 'fire'
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if isinstance(value, str):
self._name = value
else:
raise ValueError
@name.deleter
def name(self):
print('del name')
del self._name
liubei = Hero('刘备')
print(liubei.name)
liubei.name = '关羽'
print(liubei.name)
liubei.name = 100
(yiluo) ➜ Code python test.py
刘备
关羽
Traceback (most recent call last):
File "test.py", line 26, in <module>
liubei.name = 100
File "test.py", line 15, in name
raise ValueError
ValueError
1.这样的好处是可以在方法中对用户传入的数据进行校验(校验了英雄名称是字符串)
- 删除英雄
liubei = Hero('刘备')
print(liubei.name)
liubei.name = '关羽'
print(liubei.name)
del liubei.name
print(liubei.name)
(yiluo) ➜ Code python test.py
刘备
关羽
删除名字
Traceback (most recent call last):
File "test.py", line 27, in <module>
print(liubei.name)
File "test.py", line 9, in name
return self._name
AttributeError: 'Hero' object has no attribute '_name'
1.英雄已经被成功删除
欢迎下方【戳一下】【点赞】
Author:伊洛Yiluo
愿你享受每一天,Just Enjoy !