Python从0到1之面向对象

面向对象是一种抽象化的编程思想
面向对象就是将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管他内部的情况,而编程就是设置事物能够做什么事

类和对象

面向对象的过程中,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() # 静态方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值