python中面向对象编程
- 1.类(class)
- 1.1. 类的定义:
- 1.2 类的使用
- 1.2.1. 类中参数`self`
- 1.3 类的构造函数
- 1.4. Python对象销毁(垃圾回收)
- 2. 访问权限
- 2.1. 私有变量
- 2.2 私有函数
- 3. 面向对象的特点
- 3.1 继承
- 3.1.1 继承的语法
- 3.1.2. 多重继承
- 3.1.3. 检测
- 3.2 封装
- 3.3 多态
向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。
数据封装、继承和多态是面向对象的三大特点
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用
- 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。 - 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待
- 实例化:创建一个类的实例,类的具体对象。
- 方法:类中定义的函数。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法
1.类(class)
用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
1.1. 类的定义:
class Name(object) # object表示该类是从哪个类继承下来的,如果没有合适的继承类,就使用 object 类,这是所有类最终都会继承的类
attr = something # 注意需要缩进,类变量
def func(self):
pass
1.2 类的使用
class Person(Object):
name = "jim"
def dump(self):
print(f'{self.name} is dumping'} # 格式化输出参数
if __name__ == "__main__":
p = Person() # 类的实例化
print(p.name) # 通过实例化进行属性调用
p.dump() # 通过实例化进行函数调用
# jim
# jim is dumping
1.2.1. 类中参数self
-
self
是类函数中必传参数,且必须放在第一个参数位置 -
self
是一个对象,它代表实例化的变量自身 -
self
可以直接通过点来定义一个类变量 -
self
中的变量与含有self参数的函数可以在类中的任何一个函数随意调用 - 非函数中定义的变量在定义的时候不能用
self
1.3 类的构造函数
类中一种默认函数,用来将类实例化的同事,将参数传入类中。
Python中的构造函数是__init__函数。
class Person(Object):
def __init__(self,name): # 构造函数
self.name = name
def dump(self):
print(f'{self.name} is dumping'}
if __name__ == "__main__":
p = Person("亦彦") # 类的实例化
print(p.name) # 通过实例化进行属性调用
p.dump() # 通过实例化进行函数调用
# 亦彦
# 亦彦 is dumping
1.4. Python对象销毁(垃圾回收)
使用构析函数__del__
在对象销毁的时候背调用,当对象不知被使用时,__del__方法运行
def __del__(self):
class_name = self.__class__.__name__
print(class_name,"销毁")
person = Person("东尼木木","男","20",1800)
person1= person
person2= person1
print(id(person))
print(id(person1))
print(id(person2))
del person
del person1
del person2
31332048
31332048
31332048
Person 销毁
Person 销毁
2. 访问权限
# -*- coding: utf-8 -*-
class Student():
def __init__(self,name,score):
self.name= name
self.score=score
def get_information(self):
print("学生:%s,分数为:%s" % (self.name, self.score)) # 类中访问实例变量通过 self.属性名
if __name__ =="__main__":
person = Student("小明", "95")
print("修改前的属性名:", person.score) # 类外访问实例变量通过 实例名.属性名
person.get_information()
person.score = 0 # 通过实例名.属性名修改实例变量的值
print("修改后的属性名:", person.score)
person.get_information()
2.1. 私有变量
要让内部属性不被外部访问可以在属性名称前加 两个下划线(___)。在python中,实例变量名前如果以__开头,就会变成私有变量,只有内部可以访问,外部不能访问
# coding:utf-8
class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def get_information(self):
print("学生:%s,分数为:%s" % (self.__name, self.__score)) # 类中访问实例变量通过 self.属性名
if __name__ =="__main__":
person = Student("小明", "95")
print("修改前的属性名:", person.score) # 类外访问实例变量通过 实例名.属性名
# 类外部调用私有变量,会进行保存,那应该如何在外部调用和修改私有变量呢?
# AttributeError: 'Student' object has no attribute 'score'
如何在类外部访问和修改
方法一 *可以通过为类增加的 get_attrs方法或set_attrs方法来获取类中的私有变量(定义一个get_属性名的方法,set_属性名)
# coding:utf-8
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
# 方法一:
def set_name(self, name):
self.__name =name
def get_name(self):
return self.__name
def set_score(self, score):
self.__score = score
def get_score(self):
return self.__score
def get_information(self):
print("学生:%s,分数为:%s" % (self.__name, self.__score)) # 类中访问实例变量通过 self.属性名
if __name__ == "__main__":
p = Student("小明", "95")
print("修改前的属性名:", p.get_score()) # 类外访问实例变量通过 实例名.属性名
p.set_score(23)
print("修改后的属性名:", p.get_score())
p.get_information()
# 修改前的属性名: 95
# 修改后的属性名: 23
# 学生:小明,分数为:23
方法二 在类外部使用实例名._类名__变量名*的方法获取私有变量
# 方法二
print("修改前的属性名:", p._Student__name)
p._Student__name = "小牧"
print("修改后的属性名:", p._Student__name)
# 修改前的属性名: 小明
# 修改后的属性名: 小牧
2.2 私有函数
类也有私有方法。类的私有方法也是以两个下划线开头,声明该方法为私有方法,不能再类外使用。 私有方法的调用方法为self.方法名
class Student:
def __init__(self):
pass
def __func(self): # 定义一个私有方法
print("这是私有方法")
def func(self): # 定义一个公有方法
print("现在为公有方法,接下来调用私有方法")
self.__func()
student = Student()
print("通过调用公有方法来间接调用私有方法")
student.func()
# student.__func() #直接调用私有方法报错:AttributeError: 'Student' object has no attribute '__func'
3. 面向对象的特点
3.1 继承
- 通过继承基类(父类)来得到基类的功能
- 所以我们将被继承的类称作父类或者基类,继承者被称为子类
- 代码的重用
3.1.1 继承的语法
class 派生类名(基类名):
pass
在python中继承中的一些特点:
1、如果在子类中需要父类的构造方法就需要显式的调用父类的构造方法,或者不重写父类的构造方法。详细说明可查看: python 子类继承父类构造函数说明。
2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数
3、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。
3.1.2. 多重继承
语法:
派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后,如下所示:
class 派生类名(parent1,parent2,...):
pass
3.1.3. 检测
- issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)
- isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true
#coding:utf-8
class Animalia(object):
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print('{}喜欢吃饭'.format(self.name))
def introduce(self):
print("我是{},今年{}岁".format(self.name,self.age))
class dog(Animalia):
def run(self):
print("狗正在奔跑")
class cat(Animalia):
def sleep(self):
print("猫正在睡觉")
if __name__ =="__main__":
d = dog("小白",2)
d.run()
d.eat()
c = cat("呼呼",5)
c.sleep()
c.introduce()
'''
狗正在奔跑
小白喜欢吃饭
猫正在睡觉
我是呼呼,今年5岁
'''
3.2 封装
3.3 多态
子类中重写父类的方法
# -*- coding: utf-8 -*-
'''
面向对象的特点:
1.封装
2. 继承
3. 多态
'''
class Animal(object):
def run(self):
print("Animal is running")
def sleep(self):
print("Animal is sleeping")
# dog类继承Animal
class Dog(Animal):
def run(self):
print("dog is running")
def eat(self):
print("dog 喜欢吃骨头")
class Cat(Animal):
def run(self):
print("cat is runnging")
def eat(self):
print("cat 喜欢吃鱼")
def run_tuice(Animal):
Animal.run()
dog = Dog()
dog.sleep()# Animal is sleeping
dog.eat() # dog 喜欢吃骨头
run_tuice(dog) # dog 喜欢吃骨头
cat = Cat()
run_tuice(cat)# cat is runnging