面向对象是一种抽象化的编程思想
面向对象就是将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管他内部的情况,而编程就是设置事物能够做什么事
类和对象
面向对象的过程中,2个重要组成部分,类和对象
类
类是对一系列具有相同特征和行为事物的统称,是一个抽象的概念,不是真实存在的事物
特征就是属性
行为就是方法
类 比如是制造洗衣机的图纸,用类来创建对象
单下划线开始的变量为保护变量,只能在类对象和子类对象访问
双下划线开始的变量为私有变量,自能自己访问,子类对象也不能访问
对象
对象是类创造出来的真实存在的事物,如洗衣机
面向对象三大特征
封装
将属性和方法书写到类里面的操作即为封装
封装可以为属性和方法添加私有权限
继承
子类默认继承父类的所有属性和方法
子类可以重写父类的属性和方法
多态
多态指的是一类事物有多种形态(一个抽象类有多个子类,因而多态的概念依赖于继承)
定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果
传入不同的对象,产生不同的结果
class Dog(object):
def work(self):
print("指哪打哪")
class ArmyDog(Dog):
def work(self):
print("追击敌人")
class DurgDog(Dog):
def work(self):
print("追击毒品")
class Persion(object):
def work_with_dog(self,dog):
dog.work()
ad = ArmyDog()
dd = DurgDog()
Tom = Persion()
Tom.work_with_dog(ad) # 追击敌人
Tom.work_with_dog(dd) # 追击毒品
实现面向对象
定义类
类名要满足标识符命名规则,同时遵循大驼峰命名习惯
经典类:不由任意内置类型派生出的类,称之为经典类
新式类
class 类名():
代码
class Washer():
def wash(self):
return "洗衣服"
创建对象
对象又名实例
创建对象 创建对象的过程也叫实例化对象
对象名 = 类名()
class Washer():
def wash(self):
return "洗衣服"
haier = Washer()
print(haier) # <__main__.Washer object at 0x108d35f10>
haier.wash() # 洗衣服'
self
self是指调用该函数的对象
class Washer():
def wash(self):
print(self)
return "洗衣服"
haier = Washer()
# 打印self和对象的内存地址一致,都是当前对象的内存地址,所以self就是指调用该函数的对象
haier.wash() # <__main__.Washer object at 0x108d450d0> \n'洗衣服'
print(haier) # <__main__.Washer object at 0x108d35f10>
# 一个类可以有多个对象,不同对象的self地址不同
sanyang = Washer()
sanyang.wash() # <__main__.Washer object at 0x108d451d0> \n'洗衣服'
对象属性
属性即是特征,比如洗衣机的宽度、高度、重量
对象属性既可以在类外面添加和获取,也能在类里面添加和获取
类外面
class Washer():
def wash(self):
return "洗衣服"
haier = Washer()
# 添加对象属性 对象名.属性名 = 值
haier.width = 300
haier.height = 500
# 获取对象属性 对象名.属性名
haier.width # 300
haier.height # 500
类里面
class Washer():
def wash(self):
# 添加对象属性 self.属性名 = 值
self.width = 300
self.height = 500
# 获取对象属性 self.属性名
print(self.width)
print(self.height)
return "洗衣服"
haier = Washer()
haier.wash() # 300\n500\n'洗衣服'
魔法方法
init()
init()方法的作用:初始化对象,在创建一个对象时默认被调用,不需要手动调用
init(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去
class Washer():
def __init__(self):
self.width = 300
self.height = 500
def print_info(self):
print(f"洗衣机的宽度是{self.width}")
print(f"洗衣机的高度是{self.height}")
haier = Washer()
haier.print_info() # 洗衣机的宽度是300\n洗衣机的高度是500
带参数的__init__()
class Washer():
def __init__(self,width,height):
self.width = width
self.height = height
def print_info(self):
print(f"洗衣机的宽度是{self.width}")
print(f"洗衣机的高度是{self.height}")
haier = Washer(300,500)
haier.print_info() # 洗衣机的宽度是300\n洗衣机的高度是500
str()
当使用print()输出对象的时候,默认打印对象的内存地址,如果定义了__str__()方法,那么对打印从这个方法中return的数据
class Washer():
def __init__(self):
self.width = 300
def __str__(self):
return "函数说明"
haier = Washer()
print(haier) # 函数说明
del()
当删除对象时,python解释器也会默认调用__del__()方法
class Washer():
def __init__(self):
self.width = 300
def __del__(self):
print("删除对象会调用del方法")
haier = Washer()
del haier # 删除对象会调用del方法
继承
Python面向对象的继承是指多个类之间的所属关系,即子类默认继承父类的所有属性和方法
在Python中,所有类默认继承object类,object类是顶级类或者基类,其他子类叫派生类
继承:子类默认继承父类的所有属性和方法
class A(object):
def __init__(self):
self.num = 1
def print_info(self):
print(self.num)
class B(A):
pass
result = B()
# 子类继承了父类的属性和方法
print(result.num) # 1
result.print_info() # 1
单继承
一个子类只继承一个父类
class Master(object):
def __init__(self):
self.method = "传统配方"
def make_cake(self):
print(f"使用{self.method}制作蛋糕")
class Student(Master):
pass
Tom = Student()
print(Tom.method) # 传统配方
Tom.make_cake() # 使用传统配方制作蛋糕
多继承
所谓多继承,就是一个类同时继承多个父类
一个类有多个父类时,默认使用第一个继承的父类的同名属性和方法
class Master(object):
def __init__(self):
self.method = "传统配方"
def make_cake(self):
print(f"使用{self.method}制作蛋糕")
class School(object):
def __init__(self):
self.method = "网红配方"
def make_cake(self):
print(f"使用{self.method}制作蛋糕")
class Student(School,Master):
pass
Tom = Student()
print(Tom.method) # 网红配方
Tom.make_cake() # 使用网红配方制作蛋糕
多层继承
class Master(object):
def __init__(self):
self.method = "传统配方"
def make_cake(self):
print(f"使用{self.method}制作蛋糕")
class Student(Master):
pass
class NewStudent(Student):
pass
Tom = NewStudent()
print(Tom.method) # 传统配方
Tom.make_cake() # 使用传统配方制作蛋糕
重写父类同名属性和方法
子类和父类具有同名属性和方法,默认使用子类的同名属性和方法
class Master(object):
def __init__(self):
self.method = "传统配方"
def make_cake(self):
print(f"使用{self.method}制作蛋糕")
class Student(Master):
def __init__(self):
self.method = "自研配方"
def make_cake(self):
print(f"使用{self.method}制作蛋糕")
Tom = Student()
print(Tom.method) # 自研配方
Tom.make_cake() # 使用自研配方制作蛋糕
调用父类同名属性和方法
class Master(object):
def __init__(self):
self.method = "传统配方"
def make_cake(self):
print(f"使用{self.method}制作蛋糕")
class School(object):
def __init__(self):
self.method = "网红配方"
def make_cake(self):
print(f"使用{self.method}制作蛋糕")
class Student(School,Master):
def __init__(self):
self.method = "自研配方"
def make_cake(self):
self.__init__() # 注意不用加self
print(f"使用{self.method}制作蛋糕")
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
Tom = Student()
Tom.make_cake() # 使用自研配方制作蛋糕
Tom.make_master_cake() # 使用传统配方制作蛋糕
Tom.make_school_cake() # 使用网红配方制作蛋糕
Tom.make_cake() # 使用自研配方制作蛋糕
mro
类名.__mro__可以查看对象的继承关系
class Master(object):
def __init__(self):
self.method = "传统配方"
def make_cake(self):
print(f"使用{self.method}制作蛋糕")
class Student(Master):
pass
class NewStudent(Student):
pass
print(NewStudent.__mro__) # (<class '__main__.NewStudent'>, <class '__main__.Student'>, <class '__main__.Master'>, <class 'object'>)
super()
函数是用于调用父类(超类)的一个方法
super()可以自动查找父类,调用遵循__mro__类属性的顺序,比较适合单继承使用
class A():
def add(self,x):
y = x + 1
print(y)
class B(A):
def add(self,x):
super().add(x)
result = B()
result.add(2) # 3
私有权限
定义私有属性和方法
在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或实例方法不继承给子类
设置私有权限的方法:在属性和方法名前面加上2个下滑线__
子类无法继承父类的私有属性和私有方法
class A(object):
def __init__(self):
self.__money = 2000
self.house = 130
def __print_money(self):
print(self.__money)
def print_house(self):
print(self.house)
class B(A):
pass
result = B()
result.print_house() # 130
# 子类没有继承父类的私有属性和方法
result.__money # 'B' object has no attribute '__money'
result.__print_info() # 'B' object has no attribute '__print_info'
获取和修改私有属性
私有属性和方法只能在类里面访问和修改
在Python 中一般定义函数名为get_xx用来获取私有属性,定义set_xx用来修改私有属性
class A(object):
def __init__(self):
self.__money = 2000
def get_money(self):
return self.__money
def set_money(self):
self.__money = 5000
class B(A):
pass
result = B()
result.get_money() # 2000
result.set_money() # 5000
result.get_money() # 5000
类属性和实例属性
类属性
设置和访问类属性
类属性就是类对象所拥有的属性,它被该类的所有实例对象所共有
类属性可以使用类对象或实例对象访问
类属性的优点:
类的实例记录的某项数据始终保持一致时,定义类属性
实例属性要求每个对象为其单独开屏一份内存空间来记录数据,而类属性为券类所共有,仅占用一份内存,更加节省内存空间
访问类属性
class Dog(object):
touch = 10
wangcai = Dog()
# 通过类和对象访问类属性
print(Dog.touch) # 10
print(wangcai.touch) # 10
修改类属性
类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了一个实例属性
class Dog(object):
touch = 10
wangcai = Dog()
wangcai.touch = 12
print(wangcai.touch) # 12 实例对象修改等于创建了实例属性
print(Dog.touch) # 10
Dog.touch = 20 # 类对象修改类属性
print(Dog.touch) # 20
实例属性
实例属性不能通过类来访问
class Dog(object):
touch = 10
wangcai = Dog()
wangcai.touch = 12
print(Dog.touch) # 10 实例属性不能通过类访问
print(wangcai.touch) # 12
类方法和静态方法
类方法
第一个形参是类对象的方法
需要用装饰器@ classmethod来标识其为类方法,对于类方法,第一个参数必须是类对 象,一般以cls作为第一个参数
类方法一般和类属性配合使用
当方法中需要使用类对象(如访问私有类属性时),定义类方法
class Dog(object):
touch = 10
@classmethod
def get_touch(cls):
return cls.touch
wangcai = Dog()
wangcai.get_touch() # 10
静态方法
需要通过装饰器 @staticmethod 来进⾏修饰,静态⽅法既不需要传递类对象也不需要 传递实例对象 (形参没有self/cls)。
静态方法 也能够通过实例对象 和 类对象 去访问。
当⽅法中既不需要使⽤实例对象(如实例对象,实例属性),也不需要使⽤类对象 (如类属性、类法、创建实例等)时,定义静态方法
取消不需要的参数传递,有利于减少不必要的内存占⽤和性能消耗
class Dog(object):
@staticmethod
def print_info():
print("静态方法")
wangcai = Dog()
wangcai.print_info() # 静态方法
Dog.print_info() # 静态方法