Python是面向对象的一种高级语言,一切皆对象是python的基本宗旨,学习面向对象的语言,有几个重要的概念不得不掌握,不仅是因为这些基本概念是面向对象语言的基石,而且还是检验我们是否能熟练掌握一门编程语言的检验标准,那么具体有哪些相关的概念呢?我想不外乎这些-类,对象,继承,多态,封装,属性和方法等。这篇文章大致总结了一些这些基本概念的基本用法,权当是对我学习的一个回顾吧 -
1. 面向对象的基本概念
(1)类:用来描述具有相同的属性和方法的对象的集合。
(2)对象:通过类定义的数据结构实例
2. 面向对象语言的基本特性
(1)继承:子类完全继承父类的字段和方法。
(2)多态:对不同类型的变量进行相同操作,然后根据对象类型的不同表现出不同的结果。
(3)封装性:将抽象的得到的数据和功能相结合,形成一个类;封装是为了增强安全性和简化编程。
3. 如何理解这些,请看下面的代码实例(注意注释部分!) -
# 类中的函数称为方法,使用方式和一般的函数一样
# 类中的变量也称为类的属性
print(" -#2- ****************************************************************************************************")
class A(object):
def __init__(self):
self.num = 1
def info_print(self):
print(self.num)
result = A() # 创建对象result,这是实例化类的一种写法,()不能少,不然就是变量A了
result.info_print()
class B(A):
pass
result = B()
result.info_print()
# Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法
class Master: # 1. 师傅类
def __init__(self): # self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。
self.kongfu = '[星巴克的摩卡配方]'
def make_coffee(self):
print(f'运用{self.kongfu}制作咖啡')
# 以 f 开头表示在字符串内支持大括号内的python表达式
# 以 r 开头表示去除字符串中的转义字符
# 以 b 开头表示后面字符串是bytes 类型
# 以 u 开头表示后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时出现乱码
result = Master()
result.make_coffee()
class Prentice(Master): # 2. 徒弟类
pass
daqiu = Prentice()
print(daqiu.kongfu) # 对象访问实例属性
daqiu.make_coffee() # 对象调用实例方法
# 以上为单继承
# 由此可见,python3创建类的时候,可以不带括号,也可以带,也可以显示继承object,如果带个()空括号,其实也是隐式的继承了object。这三种方式是相等的
print("\n -3- ****************************************************************************************************")
class Master(object):
def __init__(self):
self.kongfu = '星巴克的摩卡配方'
def make_coffee(self):
print(f'运用{self.kongfu}制作咖啡。。。')
class School(object):
# pass
def __init__(self):
self.kongfu = '学校的摩卡咖啡配方'
def make_coffee(self):
print(f'运用{self.kongfu}来制作咖啡!!!')
class Prentice(School, Master):
pass
daqiu = Prentice() # 实例化对象时类名后需要加上()
print(daqiu.kongfu)
daqiu.make_coffee()
# 注意:当一个类有多个父类的时候,默认使用第一个父类的同名属性和方法。默认取最快一个匹配的那一个
print("\n - 4 - ****************************************************************************************************")
class Master(object):
def __init__(self):
self.kongfu = '师傅的咖啡制作配方'
def make_coffee(self):
print(f'用{self.kongfu}制作咖啡。')
class School(object):
def __init__(self):
self.kongfu = '学校教的咖啡制作配方'
def make_coffee(self):
print(f'用{self.kongfu}制作一杯咖啡~')
class Prentice(School, Master):
def __init__(self):
self.kongfu = 'My own recipe for making coffee'
def make_coffee(self):
print(f'Make a cup of coffee with {self.kongfu} @@')
result = Prentice()
result.make_coffee()
print(result.kongfu)
# 子类和父类具有同名属性和方法,默认使用子类的同名属性和方法。
print("\n - 5 - ****************************************************************************************************")
class Master(object):
def __init__(self):
self.kongfu = 'the recipe from Master'
def make_coffee(self):
print(f'Make a cup of cofee by {self.kongfu} !')
class School(object):
def __init__(self):
self.kongfu = 'the recipe from School'
def make_coffee(self):
print(f'Make a cup of cofee by {self.kongfu} @')
class Prentice(Master, School):
def __init__(self): # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
self.kongfu = 'the recipe from my original method'
def make_coffee(self):
# self.__init__()
print(f'make a cup of cofee by {self.kongfu} #')
def make_master_coffee(self): # 调用父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化
Master.__init__(self)
Master.make_coffee(self)
def make_school_coffee(self): # 调用父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化
School.__init__(self)
School.make_coffee(self)
result = Prentice()
result.make_coffee()
result.make_master_coffee()
result.make_school_coffee()
result.make_coffee()
print("\n - 6 - ****************************************************************************************************")
class Master(object):
def __init__(self):
self.kongfu = '师傅的配方!'
def make_coffee(self):
print(f'使用{self.kongfu}制作一杯咖啡!')
class School(object):
def __init__(self):
self.kongfu = '学校教的配方@'
def make_coffee(self):
print(f'使用{self.kongfu}来制作一杯咖啡@')
class Prentice(School, Master):
def __init__(self):
self.kongfu = 'my own recipe for coffee.'
def make_coffee(self):
self.__init__()
print(f'make a cup of coffeee with {self.kongfu}.')
def make_master_coffee(self):
Master.__init__(self)
Master.make_coffee(self)
def make_school_coffee(self):
School.__init__(self)
School.make_coffee(self)
# 徒孙类
class Tusun(Prentice):
pass
result = Tusun()
result.make_coffee()
result.make_school_coffee()
result.make_master_coffee()
# 多层继承关系,Prentice继承Master,School,Tusun又继承Prentice,这是多层继承的一种体现
print("\n - 7 - ****************************************************************************************************")
class Master(object):
def __init__(self):
self.kongfu = '师傅的配方!'
def make_coffee(self):
print(f'使用{self.kongfu}制作一杯咖啡!')
class School(Master):
def __init__(self):
self.kongfu = r"Alan's recipe"
def make_coffee(self):
print(f'Using {self.kongfu} to make a cup of coffee.')
# 方式 一
super(School, self).__init__()
super(School, self).make_coffee()
# 方式 二
super().__init__()
super().make_coffee()
result = School()
result.make_coffee()
# 使用super() 可以自动查找父类。调用顺序遵循 __mro__ 类属性的顺序。比较适合单继承使用。
print("\n - 8 - ****************************************************************************************************")
class Master(object):
def __init__(self):
self.kongfu = '[师傅教的制作煎饼的方法]'
def make_cake(self):
print(f'运用{self.kongfu}制作经典葱油饼')
class School(object):
def __init__(self):
self.kongfu = '[小乐经典葱油饼配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作经典葱油饼')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[独创经典葱油饼配方]'
# 定义私有属性, 设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __
self.__money = 2000000
# 定义私有方法, 设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __
def __info_print(self):
print(self.kongfu)
print(self.__money)
def make_cake(self):
self.__init__()
print(f'运用{self.kongfu}制作经典葱油饼')
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
# 徒孙类
class Tusun(Prentice):
pass
daqiu = Prentice()
# 对象不能访问私有属性和私有方法, 注意这里说的是对象,即对象不能访问类中的私有属性和方法
# print(daqiu.__money)
# daqiu.__info_print()
xiaoqiu = Tusun()
# # 子类无法继承父类的私有属性和私有方法,这是显而易见的,因为父类的对象都不能访问私有属性,那么子类对象更加没法访问父类的私有属性了
# print(xiaoqiu.__money) # 无法访问实例属性__money
# xiaoqiu.__info_print()
# # 私有属性和私有方法只能在类里面访问和修改。
print("\n - 9 - ****************************************************************************************************")
class Master(object):
def __init__(self):
self.kongfu = '[师傅教的制作煎饼的方法]'
def make_cake(self):
print(f'运用{self.kongfu}制作经典葱油饼')
class School(object):
def __init__(self):
self.kongfu = '[小乐经典葱油饼配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作经典葱油饼')
class Prentice(School, Master):
def __init__(self):
self.kongfu = '[独创经典葱油饼配方]'
self.__money = 2000000
# 获取私有属性
def get_money(self):
return self.__money
# 修改私有属性
def set_money(self):
self.__money = 5000
def __info_print(self):
print(self.kongfu)
print(self.__money)
def make_cake(self):
self.__init__()
print(f'运用{self.kongfu}制作经典葱油饼')
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
# 徒孙类
class Tusun(Prentice):
pass
# 实例定义 - 在类名后+()
daqiu = Prentice()
daqiu.__moneyq = 222
print(daqiu.__moneyq)
print(daqiu.__class__)
print("seee this one - ", Prentice.__bases__)
print(daqiu.__dict__)
print(daqiu.get_money())
daqiu.set_money()
print(daqiu.get_money())
print("see what's this - ", daqiu._Prentice__money) # 其实还是可以访问 __money ,可以通过 daqiu._Prentice__money 访问到 __money 属性,为什么能这么访问这里不多讲,他与python的机制有关。
xiaoqiu = Tusun()
# 调用get_money函数获取私有属性money的值
print(xiaoqiu.get_money())
# 调用set_money函数修改私有属性money的值
xiaoqiu.set_money()
print(xiaoqiu.get_money())
# 在Python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性值。
4. 一点总结 -
对象属性和雷属性的几点理解 - 对象属性和类属性
- 使用对象创建的属性 称之为对象属性 只有当前对象里才存在
- 如果使用对象属性创建了一个和类里面同名的属性 那么调用的时候 会优先查找对象里面的属性
- 使用类里面的方法的参数 self 创建的属性 也为对象属性
- 当使用对象.属性名来改类里面的属性的时候 其实是在对象里面创建了一个同名的属性
- 当将对象里面同名的属性删除掉以后 还是会调用类的属性
- 不能再对象里 删除 类里面的属性 只有使用的权利
- 使用类操作过的属性 所有对象在调用类属性的时候 都是修改后的属性
类的私有属性和私有方法
私有属性 和 私有方法
(1) 类的私有属性:以__ 作为开头 不能再类的外部进行使用和访问 在类的里面使用 self.__属性名
私有属性的访问
在类的外部: 对象._类名__属性名 查找
在类的内部: 方法里面的变量 self._属性名 调用
注意: 在类的内部只要使用self._属性名 那么就会去找私有属性_类名__属性名
(2) 类的私有方法
以_ 作为开头 不能再类的外部进行使用和访问 在类的里面使用 self.__方法名
在公有方法里面 通过self去调用
类的常用属性
__doc__ 类的说明
__name__返回类名
__base__ 返回一个父类
__bases__ 返回多个父类
__dict__ 返回对象或者类的信息