首页 > 其他分享 >面向对象的对象的三大特性

面向对象的对象的三大特性

时间:2024-02-26 21:44:55浏览次数:23  
标签:__ self 特性 面向对象 三大 print 父类 class def

一、封装

封装是一种将数据和相关方法组合成一个单独的实体的机制。它将数据(属性)和操作数据的方法(方法)封装在一个对象中,并对外部代码隐藏了内部的实现细节。通过封装,对象可以提供一个公共接口,使得外部代码可以通过该接口访问和操作对象的数据,而不

需要了解其内部的具体实现。

 

封装之后:可以使用对象.属性的方法,不需要记所有的方法和属性。 掩藏属性  

二、继承

继承是新建类的一种方式,新建出来的类称作子类,被继承的类叫父类

它允许新类(子类)继承现有类(父类)的属性和方法,并且可以在新类中添加新的属性和方法,或者重写父类的方法来定制子类的行为。

继承促进了代码的重用和扩展(),并且提供了层次化和组织化的代码结构。解决了类与类之间的代码冗余问题

1、为什么要继承?
类解决什么问题:解决的是对象与对象之间的代码冗余问题
继承解决什么问题:解决的是类与类之间的代码冗余问题

2、子类的继承可以有多个父类

1 2 3 4 5 6 7 8 9 10 11 12 13 class Parent1(object):     pass   class Parent2:     pass   # 子类 class Sub1(Parent1):     pass   # 多继承, 括号里面可以写多个类 class Sub2(Parent1, Parent2):     pass

3、查看一个类继承了哪些父类,.__bases__方法

1 2 3 print(Sub1.__bases__) # (<class '__main__.Parent1'>,) print(Sub2.__bases__) # (<class '__main__.Parent1'>, <class '__main__.Parent2'>) print(Parent1.__bases__)  # (<class 'object'>,)

注:python3中新定义的父类默认继承的是object类,所以父类也是一个子类

4、继承小案例

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class People:  # 定义一个父类     school = 'SH'  # 严格依赖继承       def __init__(self, name, age, gender):         self.name = name         self.age = age         self.gender = gender   class Student(People):     def __init__(self, name, age, gender, course):         """这个是指名道姓的调用方法,不依赖于继承"""         People.__init__(self, name, age, gender)  # name, age, gender 继承父类的属性         self.course = course       # 选课     def choose_course(self):         pass   class teacher(People):     def __init__(self, name, age, gender, level):         People.__init__(self, name, age, gender)         self.level = level  # 教室职称   stu = Student('kevin''19''male''python') teacher1 = teacher('王刚'40'male''高级教师') print(stu.name)  # kevin print(teacher1.level)  # 高级教师

5、单继承下的属性查找

先从对象自己的名称空间中查找,然后去产生这个对象的类中查找,最后在去继承的父类中查找

6、多继承下的属性查找

多继承下的属性查找分为:菱形查找和非菱形查找

菱形查找分:经典类和新式类
经典类:按照深度优先查询
新式类:按照的广度优先查询

非菱形查找

注:在python3 中都是新式类

所以,多继承下的属性查找,如果属性找不到,就按照广度优先查询

菱形查找:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class G(object):     def test(self):         print('from G')   class E(G):     def test(self):         print('from E')   class F(G):     def test(self):         print('from F')   class B(E):     def test(self):         print('from B')   class C(F):     def test(self):         print('from C')   class D(G):     def test(self):         print('from D')   class A(B,C,D):     # def test(self):     #     print('from A')     pass   obj = A() obj.test() # 如上图,查找顺序为:obj->A->B->E->C->F->D->G->object # 可依次注释上述类中的方法test来进行验证

⚠️:

1. 广度优先查找:从B开始到E回头,C到F,即查找到根部的上一级,最后一个分支查找到根部G

2. 如果D分支没有继承G,会在F查找完后查找G,形成菱形查找

7、super()内置函数与mro列表

super()是一个内置函数,用于调用父类的方法。它提供了一种方便的方式来访问父类的属性和方法,从而实现方法重写和继承(派生)。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class ParentClass:     def __init__(self):         self.parent_attr = "I am the parent class"       def some_method(self):         print("This is the parent class method")     class ChildClass(ParentClass):     def __init__(self):         super(ParentClass, self).__init__() # python2 的写法,python3 兼容调构造方法         self.child_attr = "I am the child class"       def some_method(self):         super().some_method()  # python2 的写法不支持         print("This is the child class method")     # 创建子类对象 child = ChildClass()   # 访问子类和父类的属性 # print(child.child_attr)  # 输出: I am the child class # print(child.parent_attr)  # 输出: I am the parent class   # 调用子类和父类的方法 child.some_method()   # 输出: # This is the parent class method # This is the child class method

如果不用super()方法来实现派生与方法重用:

指名道姓的调用某一个类的函数(不依赖于继承)

派生:比父类多的功能,派生方法。

相同的方法:重写

1 2 3 4 5 6 7 8 class ChildClass(ParentClass):     def __init__(self):         ParentClass.__init__(self)         self.child_attr = "I am the child class"       def some_method(self):         ParentClass.some_method(self)         print("This is the child class method")

mro列表

mro(Method Resolution Order)是指在多重继承中确定方法调用顺序的算法。Python中的每个类都有一个mro列表,它决定了方法解析的顺序。

MRO列表可以通过__mro__属性来访问,它是一个元组,按照方法解析顺序列出了类及其超类。MRO列表遵循C3线性化算法,它考虑了类的继承关系和方法重写,以确保方法的解析顺序是一致且合理的。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class A:     def some_method(self):         print("Method from class A")   class B(A):     # def some_method(self):     #     print("Method from class B")     pass   class C(A):     def some_method(self):         print("Method from class C")   class D(B, C):     # def some_method(self):     #     print("Method from class D")     pass   # 创建类D的实例 = D()   # 调用some_method()方法 d.some_method()   # 打印MRO列表 print(D.__mro__)

输出结果

1 2 # Method from class C # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

从结果可以看出:查找遵循了广度优先原则

三、多态

一种事物的多种形态,比如动物类会发出叫声,但是不同的动物叫声是不一样的

1、概念

允许不同的对象通过相同的接口进行交互,而无需关注对象的具体类型。多态使得我们可以编写更加灵活和通用的代码,提高代码的可重用性和可扩展性。

多态的实现依赖于继承和方法重写的机制。当多个类继承自同一个父类,并且这些子类都实现了父类的方法,那么这些子类对象可以被视为父类对象的多态形式。

多态性的关键在于子类对象可以被赋值给父类对象的变量,然后通过父类的接口来调用方法。在编译时,编译器会根据变量的声明类型选择适当的方法。而在运行时,实际上调用的是子类对象的方法。

多态实现了面向对象编程中的一个重要原则:针对接口编程,而不是针对实现编程。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Animal:     def make_sound(self):         pass   class Dog(Animal):     def make_sound(self):         print("Woof!")   class Cat(Animal):     def make_sound(self):         print("Meow!")   def make_animal_sound(animal):     animal.make_sound()   # 创建不同的子类对象 dog = Dog() cat = Cat()   # 通过父类接口调用方法 make_animal_sound(dog)  # 输出: Woof! make_animal_sound(cat)  # 输出: Meow!

⚠️:

1. 在此案例中Animal为父类,要求子类对象dog和cat有制造声音的功能。

2. dog和cat通过同一个接口传入,输出不同的结果

3. 此处的Animal 父类没有强制要求子类实现制造声音的功能,是一种思想,可以删掉Animal实现相同的效果

2、父类强制子类拥有相同的属性或方法

抽象类和抽象方法,用到abc模块,是abstract 抽象的英文缩写

class Animal(metaclass=abc.ABCMeta): 先变成抽象类,@abc.abstractmethod变成抽象方法

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #  强制子类有某种属性方法 import abc   class Animal(metaclass=abc.ABCMeta):     @abc.abstractmethod     def speak(self):         pass       @abc.abstractmethod     def run(self):         pass   class Cat(Animal):     # def speak(self):     def test(self):         print('miaomiao')   class Dog(Animal):     def speak(self):         print('wangwang!')   cat = Cat() print(cat.test()) # TypeError: Can't instantiate abstract class Cat with abstract methods run, speak

注:用上抽象类以后,子类没有遵循限制,实现相关的功能就会报错

1. 类传入 ‘metaclass=abc.ABCMeta’成为抽象类, 方法使用@abc.abstractmethod装饰器,成为抽象方法。

2. 抽象类本身不能被实例化和直接调用,它主要用于作为其他类的基类(父类)。

3. 抽象类的主要目的是为了定义一组通用的属性和方法,供子类继承和实现。 

3、鸭子类型

抽象类的强制限制,这种方式是python不推荐的,python推荐的是鸭子类型

鸭子类型是一种思想,它关注对象的行为而不是对象的类型

根据鸭子类型的理念,如果一个对象具有与鸭子相似的行为特征,那么它可以被视为鸭子。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Duck:     def quack(self):         print("Quack!")       def fly(self):         print("Flying!")   class Robot:  # 机器人     def quack(self):         print("Beep!")       def fly(self):         print("Unable to fly!")   def make_quack_and_fly(obj):  # quack 嘎嘎叫声     obj.quack()     obj.fly()   duck = Duck() robot = Robot()   make_quack_and_fly(duck)  # 输出: Quack!  Flying! make_quack_and_fly(robot)  # 输出: Beep!  Unable to fly!

注:

定义了两个类,实例化一个鸭子和机器人,通过统一的函数接口调用方法(quack、fly),得到不同的结果

4、组合

一个对象拥有的属性或者方法,该属性或方法的被另外一个对象调用

案例1: 学生和选课

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class People:     def __init__(self, name, age, gender):         self.name = name         self.age = age         self.gender = gender   class Course:     def __init__(self, course_name, course_price, course_period):         self.course_name = course_name         self.course_price = course_price         self.course_period = course_period   # 实例化课程 python = Course("python"10000'6mon') linux  = Course("linux"20000'5mon')   class Student(People):     def __init__(self, name, age, gender, course=None):         if course is None:             course = []         super(Student, self).__init__(name, age, gender)         self.courses = course     # def choose_course(self):     #     pass   stu = Student('kevin''19''male')   stu.courses.append(python)  # stu.courses ====> [python对象] stu.courses.append(linux)   # stu.courses ====> [python对象, linux对象] # print(stu.courses) print(stu.courses[0].course_name) print(stu.courses[0].course_price)

案例2:car汽车对象使用了另一个类Engine中的函数功能,也是一种组合

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Engine:     def start(self):         print("Engine started.")       def stop(self):         print("Engine stopped.")   class Car:     def __init__(self):         self.engine = Engine()  # Car类包含Engine类对象       def start(self):         print("Car starting.")         self.engine.start()       def stop(self):         print("Car stopping.")         self.engine.stop()   car = Car() car.start() car.stop()   # 输出 Car starting. Engine started.   Car stopping. Engine stopped.

案例3:商品和订单的组合关系

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Product:     def __init__(self, name, price):         self.name = name         self.price = price       def info(self):         print(f"Product: {self.name}, Price: ${self.price}")   class Order:     def __init__(self, order_id):         self.order_id = order_id         self.products = []       # 添加商品     def add_product(self, product):   # 接收一个实例对象(包括对象的所有属性和方法)         self.products.append(product)       # 展示商品     def display(self):         print(f"商品订单: {self.order_id}")         print("商品展示:")         for product in self.products:  # 实例对象列表,每次循环都是一个实例             product.info()   # 商品实例调用商品对象的内部info方法,打印商品名和价格信息             print("-----------")   # 创建产品,实例化过程 product1 = Product("Phone"999) product2 = Product("Laptop"1499) product3 = Product("Headphones"199)   # 创建订单,实例化过程 order = Order("ORD-123") order.add_product(product1)  # 把实例传进去 order.add_product(product2) order.add_product(product3)   # 显示订单信息,order是一个实例对象 order.display()

标签:__,self,特性,面向对象,三大,print,父类,class,def
From: https://www.cnblogs.com/Jessica-Jmm/p/18035644

相关文章

  • C# 面向对象
     C#面向对象前言#C#是一种面向对象、类型安全的语言。❓什么是面向对象面向对象编程(OOP)是如今多种编程语言所实现的一种编程范式,包括Java、C++、C#。面向对象编程将一个系统抽象为许多对象的集合,每一个对象代表了这个系统的特定方面。对象包括函数(方法)和......
  • 面向对象,到底是个什么鬼? (设计模式)
    什么才算是面向对象编程语言面向对象是支持类对性得语法机制,并有现成得语法机制,能方便得实现面向对象得封装,继承多态,抽象。 一般来讲,面型对象编程,是通过面向对像得编程语言来进行得,但是不用面型对象编程语言,我们照样可以进行面向对象编程,反过来讲,即使我们使用面向像得语言写出......
  • python——面向对象——知识汇总二
    Pythonproperty()函数:定义属性 我们一直在用“类对象.属性”的方式访问类中定义的属性,其实这种做法是欠妥的,因为它破坏了类的封装原则。 正常情况下,类包含的属性应该是隐藏的,只允许通过类提供的方法来间接实现对类属性的访问和操作。因此,在不破坏类封装原则的基础上,为了能......
  • python——面向对象——知识汇总
    面向对象技术简介类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。方法:类中定义的函数。类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。......
  • Ehcache 介绍(1)--Ehcache 功能特性
    Ehcache是一个开源的、基于标准的缓存工具,它能提升性能、减轻数据库负载并简化可扩展性。由于其稳健性、经得起考验的特点以及与其他流行框架的集成,Ehcache成为最广泛使用的基于Java的缓存工具。Ehcache从进程内缓存一直扩展到混合的进程内/进程外部署,可以处理TB的数据。1......
  • 美团面试:说说OOM三大场景和解决方案? (绝对史上最全)
    首先,咱们先聊聊,什么是OOM?小伙伴们,有没有遇到过程序突然崩溃,然后抛出一个OutOfMemoryError的异常?这就是我们俗称的OOM,也就是内存溢出。简单来说,就是你的Java应用想要的内存超过了JVM愿意给的极限,就会抛出这个错误。那么为什么会出现OOM呢?一般都是由这些问题引起:分配过少:JVM......
  • C#版本与.NET版本对应关系以及各版本的特性
    C#版本.NET版本发布日期特性C#1.0.NETFramework1.02002-02-13委托、事件C#1.1.NETFramework1.12003-04-24APM(异步编程模型)C#2.0.NETFramework2.02005-11-07泛型、匿名方法、迭代器、可空类型C#3.0.NETFramework3.02007-11-06隐式类型......
  • 【触想智能】工控一体机与PLC电脑的三大区别
    工控一体机与PLC电脑都是工业自动化控制中使用非常广泛的设备。虽然它们都是一体化设备,但是它们的设计和功能是不同的。很多客户朋友对工控一体机和PLC电脑分不清,下面小编为大家介绍一下它们之间的区别。1、设计结构:工控一体机是一种将计算机和控制器集成在一......
  • 鸿蒙的技术特性
    硬件互助,资源共享多种设备之间能够实现硬件互助、资源共享,依赖的关键技术包括分布式软总线、分布式设备虚拟化、分布式数据管理、分布式任务调度等。分布式软总线分布式软总线是手机、平板、智能穿戴、智慧屏、车机等分布式设备的通信基座,为设备之间的互联互通提供了统一的分布......
  • java面向对象之封装-抽象-继承-组合-多态五种概念一网打尽
    说明曾经在学习java面向对象时,你是否会为面向对象的封装-继承-抽象-多态-组合等各种概念搞得稀里糊涂,乃至反复阅读,背诵其相关概念,结果一段时间过后又还给了时间。。。这种经历简直令人发指,让人无法忍受,难道就没有哪个地方能把它一次说清楚,老百姓看了以后纷纷醍醐灌顶,不再重蹈覆......