面向对象的编程

面向过程   着重于做什么
面向对象 oop 着重于谁去做

程序员 看作是造物主

类:具有相同属性和方法的对象的集合
对象 (实例):实实在在的例子,某一个类实例化之后的结构体

  • 类(Class)

    • 对象的蓝图或模板,定义对象的属性(对象的描述信息,静态数据)方法(行为)

    • 例如:汽车类 可以有属性 颜色品牌,方法 启动()刹车()

  • 对象(Object)

    • 类的实例,具有具体的属性值和方法实现。

    • 例如:一辆红色特斯拉汽车 是 汽车类 的一个对象。

优势:便于代码管理,方便迭代更新

python :

class User():
    school = "sctl"
    def __init__(self,name,age,address,passwd):
        self.name = name
        self.age = age
        self.address = address
        self.passwd = passwd
print(f"类空间:{User.__dict__}")
print(User.school)
user1 = User("张三",20,'changsha',123456)
user2 = User("lisi",22,"wuhan","lisi123")
print(f"实例空间1:{user1.__dict__}")
print(user1.name,user2.address,user1.school,user2.school)
user1.school = "sanchuang"
print(user1.school,user2.school)

类空间:{'__module__': '__main__', 'school': 'sctl', '__init__': <function User.__init__ at 0x000001B97716A050>, '__dict__': <attribute '__dict__' of 'User' objects>, '__weakref__': <attribute '__weakref__' of 'User' objects>, '__doc__': None}
sctl
实例空间1:{'name': '张三', 'age': 20, 'address': 'changsha', 'passwd': 123456}
张三 wuhan sctl sctl
sanchuang sctl

属性查找:

1、先在当前实例空间查找属性和方法,找到即刻返回
2、如果在实例空间没找到,通过类对象指针,去类空间查找
3、类空间没有,就去父类查找

实例化的两步过程:

1、创建一个实例:
user1 = User.__new__(User) 
User没有new方法,是调用父类的,所以要传递参数,指定创建哪个类的实例,也可以写作
user1 = object__new__(User)

2、对实例进行初始化工作
user1.__init__("zhangsan","123456")
user1同样也是用的类空间里的init方法,也可以写作执行的是User.__init__
这时就需要多一个参数,指定哪个实例去使用,写为User.__init__(user1,"zhangsan","123456")

这两步可以简写为user1 = User("zhangsan","123456")

__new__和__init__的区别:
 

特性__new____init__
职责创建实例初始化实例
第一个参数cls(类)self(实例)
返回值必须返回实例对象无返回值
执行顺序先执行后执行
应用场景单例、不可变类型、动态实例生成常规属性初始化

静态方法、实例方法、类方法

class User():
    money = 2000
    def __init__(self,name,passwd):
        self.name = name
        self.passwd = passwd
        self.money = 5000

    def chongzhi(self,amount): #实例方法,普通方法,第一个参数无须传递,代表实例本事
        self.money += amount
        print(f"充值了{amount},还剩{self.money}")

    @classmethod #被这个装饰器装饰的方法,称为类方法,第一个参数无须传递,代表类本身
    def chongzhi2(cls,amount):
        cls.money += amount
        print(f"充值了{amount},还剩{cls.money}")

    @staticmethod #被这个装饰的方法,称为静态方法,无需强制参数
    def chongzhi3(amount):
        User.money += amount
        print(f"充值了{amount},还剩{User.money}")
user1 = User("zhangsan","123456")
user1.chongzhi(1000)
user1.chongzhi2(1000)
user1.chongzhi3(1000)

面向对象三大特点:封装、继承、多态

经典类和新式类(经典类的定义在python3中没有了)

特性经典类(Python 2.x 默认)新式类(Python 3.x 唯一类型)
继承自不显式继承任何类必须直接或间接继承 object
定义方式class MyClass:class MyClass(object):(Python 2)
class MyClass:(Python 3)
继承属性方法解析顺序(MRO)深度优先(Depth-First)C3 线性化算法(更合理的多继承顺序)

关于继承,子类会继承父类的方法

class Animal:
    def __init__(self):
        self.spical = 'dog'
        def eat(self):
            print("i can eat")
class Cat(Animal):
    pass
a=Cat()
print(a.spical)

  这里Cat会继承Animal的__init__方法,所以spical='dog'在a生成时同步生成,属性查找时就在当前的实例中查找。

子类重写(Override) 是指子类通过定义与父类同名的方法或属性,覆盖父类的实现,从而实现 自定义行为 或 扩展功能。子类如果如果想在保留父类的属性前提下,再额外添加属性,可用super方法实现

class Person:
    def __init__(self, name):
        self.name = name

class Student(Person):
    def __init__(self, name, student_id):
        super().__init__(name)
        self.student_id = student_id  # 新增属性

stu = Student("小明", "S001")
print(stu.name)        # 输出:小明(继承自父类)
print(stu.student_id)  # 输出:S001(子类新增)

像工厂函数也是一种类

例:自定义一个可以进行值排序的字典

class Mydict(dict):
    def sort(self):
        return dict(sorted(self.items(),key=lambda x:x[1],reverse=True))
d1=Mydict()
d1['x'] = 1
d1['y'] = 4
d1['z'] = 2
print(d1)
print(d1.sort)
#判断类型
print(type(d1),type("abc"))
print(isinstance(d1,Mydict))
print(isinstance(d1,dict))

多态 -- 接口不同形态

python原生支持多态,不需要额外的实现

多态性的实现方式

1. 基于继承和方法重写(运行时多态
class Animal:
    def speak(self):
        raise NotImplementedError("子类必须实现此方法")

class Dog(Animal):
    def speak(self):  # 重写父类方法
        return "汪汪!"

class Cat(Animal):
    def speak(self):  # 重写父类方法
        return "喵喵!"

def animal_sound(animal: Animal):
    print(animal.speak())

# 同一函数处理不同对象
animal_sound(Dog())  # 输出:汪汪!
animal_sound(Cat())  # 输出:喵喵!
2. 基于鸭子类型(动态类型)

Python 不强制要求类型继承,只要对象有对应方法即可视为“兼容”: 

class Duck:
    def quack(self):
        print("鸭子叫:嘎嘎!")

class Person:
    def quack(self):  # 无需继承,只需同名方法
        print("人模仿鸭子叫:嘎嘎!")

def make_quack(obj):
    obj.quack()

make_quack(Duck())   # 输出:鸭子叫:嘎嘎!
make_quack(Person()) # 输出:人模仿鸭子叫:嘎嘎!

私有成员

魔术方法:

魔术方法(Magic Methods),也称为 特殊方法(Special Methods) 或 双下方法(Dunder Methods),是 Python 中用于定义类行为的一组内置方法。它们以双下划线(__)开头和结尾,例如 __init____str__ 等。魔术方法允许开发者自定义类的行为,使其更符合 Python 的内置协议。

type -- 元类 创建类的类
object -- 继承的顶点,是所有类的基类

抽象基类(定义接口规范,不能实例化,用于强制规范子类的行为)
 

from abc import ABC, abstractmethod

# 定义一个抽象基类
class Shape(ABC):
    @abstractmethod
    def area(self):
        """子类必须实现此方法"""
        pass

    @abstractmethod
    def perimeter(self):
        pass

# 子类继承抽象基类
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

    def perimeter(self):
        return 2 * 3.14 * self.radius

# 尝试实例化
c = Circle(5)
print(c.area())  # 输出 78.5

# 如果子类未实现所有抽象方法,会报错!
class Square(Shape):
    def area(self):
        return self.side ** 2

s = Square()  # TypeError: 未实现 perimeter 方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值