【Python】面向对象
第八节:Python面向对象编程
一、类和对象
面向对象是一种抽象化的编程思想,很多编程语言中都有的一种思想。 一切皆对象
类:是对一系列具有相同 特征 和 行为 的事物的统称。
对象:对象是基于类创建出来的真实存在的事物。
1、定义类
class 类名():
属性1
属性2
属性3
函数1
函数2
......
注意:类名要满足标识符命名规则,同时遵循:大驼峰命名习惯
2、创建对象
对象名(变量) = 类名()
创建对象的过程也叫实例化对象。
3、self是什么意思?
self:指的是当前的对象。
4、访问对象的属性和函数
-
类外面访问
对象名.属性名字 对象名.函数名字
-
类里面访问
self.属性名字 self.函数名字
二、魔术函数
在Python中,__xx__()
的函数叫做魔法方法,指的是具有特殊功能 或者 有特殊含义的函数。而且这些函数都是在某种情况下自动调用的。
1、init函数
__init__(): 对象的初始化函数
__init__(),在创建一个对象时默认被调用,不需要手动调用
__init__(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去。
2、str函数
当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了 __str__
方法,那么就会打印从在这个函数中 return 的数据。
3、del函数
当删除对象时,python解释器也会默认调用 __del__()
函数。
三、类属性和实例属性
1、类属性
class Person(object):
type_name = '人类'
类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了一个实例属性。
四、类函数和静态函数
1、类函数
需要用装饰器 @classmethod
来标识其为类函数,对于类函数,第一个参数必须是类(当前类),一般以 cls
作为第一个参数。但是:也可以命名其他的。一般习惯上都用cls。
class Person(object):
type_name = '人类'
@classmethod
def get_tooth(cls):
return cls.type_name
2、静态函数
需要通过装饰器 @staticmethod
来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)。静态方法 也能够通过 实例对象 和 类对象 去访问。
特点:
第九节:继承和多继承
一、继承
Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和函数。
在Python中,所有类默认继承object类,object类是顶级类或基类;
1、单继承
class Fruit:
color = '绿色'
def harvest(self, color):
print(f"水果是:{color}的!")
print("水果已经收获...")
print(f"水果原来是{Fruit.color}的!")
class Apple(Fruit):
color = "红色"
def __init__(self):
print("我是苹果")
class Orange(Fruit):
color = "橙色"
def __init__(self):
print("\n我是橘子")
apple = Apple() # 实例化Apple()类
apple.harvest(apple.color) # 在Apple()中调用harvest函数,并将Apple()的color变量传入
orange = Orange()
orange.harvest(orange.color) # 在Orange()中调用harvest,并将Orange()的color变量传入
在编写类时,并不是每次都要从空白开始。当要编写的类和另一个已经存在的类之间存在一定的继承关系时,就可以通过继承来达到代码重用的目的,提高开发效率。
2、函数的重写
父类(被继承的类)的函数都会被子类(继承的新类)继承,当基类(父类)中的某个函数不完全适用于子类时,就需要在子类中重写父类的这个函数。 而且函数的名字必须一模一样。
#父类
class Person:
def __init__(mysillyobject, firstname, lastname):
mysillyobject.name = firstname
mysillyobject.family = lastname
def myfunc(abc):
print("Hello my name is " + abc.name)
#子类,继承
class Student(Person):
def __init__(self, fname, year, lname):
super().__init__(fname, lname) # 调用父类的属性赋值函数
self.graduationyear = year #子类自己的属性
def welcome(self):
#子类自己的函数
print("Welcome", self.name, self.family, "to the class of", self.graduationyear)
x = Student("Elon", 2019, "Musk")
x.welcome(
Python 还有一个 super()
函数,通过使用 super()
函数,在重写父类函数时,让super().调用在父类中封装的函数.
如果在开发中,子类的函数中包含父类的函数,父类原本的函数是子类函数的一部分,就可以采用扩展的方式。
扩展的方式步骤:
- 在子类中重写父类的函数
- 在需要的位置使用 super().父类函数 来调用父类函数的执行
- 代码其他的位置针对子类的需求,编写子类特有的代码实现
二、多继承
在python中是可以多继承的,继承的先后顺序是有区别的,当我们调用函数的时候,如果第一个继承的找不到,才会去第二个中找,但是只要在第一个类中找到调用的那个函数,即使参数个数不匹配也不会调用第二个父类中的,此时会报错。
MRO顺序:Python官方采用了一个算法将复杂结构上所有的类全部都映射到一个线性顺序上,而根据这个顺序就能够保证所有的类都会被构造一次。
类名字.__mro__
三、私有属性和函数
在Python中,可以为实例属性和函数设置私有权限,即设置某个实例属性或实例函数不继承给子类。甚至,不能在类的外部调用和访问
设置私有权限的方法:在属性名和函数名 前面 加上两个下划线 __。
如果也想要别人去访问和修改私有属性,在Python中,一般定义函数名 get_xx
用来获取私有属性,定义 set_xx
用来修改私有属性值。
作者:道友老李