7.25面向对象

面向对象

1.面向对象是什么?

  是一种编程思想,核心就在对象

  将程序看做一堆对象的集合,程序的功能就是控制调度对象来交互完成

2.为什么使用面向对象

  优点:扩展性高,可维护性好,灵活,重用性高

  缺点:程序结构更加复杂,无法预知执行结果

3.类和对象

  类:是一系列具备相同特征和行为的对象的集合体,是一种抽象概念

  对象:是具备某些特征和行为的集合体,是具体存在的某个事物

  类包含多个对象,对象属于某个类型

4.定义

  写法:class 类名称:

        类的内容

  类名称大驼峰

  创建对象:类名称()

5.属性的正确使用

  对象公共的部分放到类中

  每个对象独有的放在对象自己的名称空间中

6.初始化函数

  用来给对象赋初始值,和一些别的初始化逻辑

7.绑定方法

  (1)对象和函数,对象绑定方法

    当使用对象调用时会自动传入对象本身作为第一个参数

    如果使用类名调用,那就是普通函数需要自己传值

  (2)类和函数,类绑定方法:@classmethod

    用类或对象调用都会传入类本身

8.非绑定方法:@staticmethod

  就是一个普通函数,不会自动传值

9.场景

  当函数的逻辑中需要访问对象时,那就绑定给对象,仅需要类中数据就绑定给类

  属性的查找顺序,先找对象自己的名称空间,找不到在找类的名称空间,类找不到找他的父类

继承

1.什么是继承

  继承是一种关系,描述两个对象之间,什么是什么的关系,例如麦兜,佩奇,猪刚鬣 都是猪

  在程序中,继承描述的是类和类之间的关系,例如a继承了b, a就能直接使用b已经存在的方法和属性,a称之为子类,b称之为父类,也称之为基类 

2.为什么要使用继承

  继承的一方可以直接使用被继承一方已经有的东西

  其目的是为了重用已经有的代码,提高重用性

3.如何使用继承

  基本语法:

class Base:
    desc = "这是一个基类"
    def show_info(self):
        print(self.desc)

    def make_money(self):
        print("一天赚一个亿...")

#指定父类位Base
class SubClass(Base):
    pass

obj = SubClass()
#即使类中什么都没有也可以使用父类中已有的内容
obj.make_money()
print(obj.desc)
View Code

  在python中 一个子类可以同时继承多个父类

4.抽象

  特点:不具体,不清晰,很模糊,看不懂

  将多个子类中相同的部分,进行抽取,形成一个新的类,这个过程也称之为抽象的过程

5.如何正确的使用继承

  1.先抽象在继承

  2.继承一个已经现存的类,扩展或是修改原始的功能

属性的查找顺序

  对象自己的 -> 所在类中 -> 找父类 ->父类的父类 ->Object

派生

  当一个子类中出现了与父类中不同的内容时,这个子类就称之为派生类

  通常子类都会写一些新的代码,不可能和父类完全一样,既通常都是派生类

  所以派生类指的就是子类

覆盖

  也称之为重写:overrides

  当子类出现了与父类名称完全一致的属性或方法时,会覆盖父类的,导致无法查找到父类的属性或方法

class Person:
    def say_hi(self):
        print("hello")

class Student(Person):
    def say_hi(self):
        print("hello world!")

stu = Student()
stu.say_hi()  # hello world!

如何实现一个能够限制元素类型的列表类

class MyList(list):
    def __init__(self,element_type):
        super().__init__() # 调用父类的初始化方法 来完成基本的初始化
        self.element_type = element_type

    def append(self, object):
        """
        :param object: 是要存储的元素
        :return: 没有
        """
        if type(object) == self.element_type:
            #我们需要在这里访问父类的append函数来完成真正的存储操作
            super().append(object)
        else:
            print("sorry sir, you element type not is %s" % self.element_type)

# 创建时指定要存储的元素类型
m = MyList(int)
# 当你有需求,是需要在创建对象时 干点什么事儿  那就该想到初始化方法
m.append(1)
print(m[0])
m.append("字符串")

子类中访问父类的内容

1.三种方法

  方式1:super(当前类名称,self).你要调的父类的属性或方法

class Parent:
    text = "abc"
    def say_something(self):
        print("anything")

class Sub(Parent):
    def show_info(self):
        print(super(Sub,self).text)
        super(Sub,self).say_something()

sub = Sub()
sub.show_info()

  方式2:super().你要调的父类的属性或方法,py3的新语法,最常用的方式

class Parent:
    text = "abc"
    def say_something(self):
        print("anything")

class Sub(Parent):
    def show_info(self):
        print(super().text)
        super().say_something()

sub = Sub()
sub.show_info()

  方式3:类名称.你要调的父类的属性或方法(self),方式3与继承无关

class Parent:
    text = "abc"
    def say_something(self):
        print("anything")

class Sub(Parent):
    def show_info(self):
        print(Parent.text)
        Parent.say_something(self)

sub = Sub()
sub.show_info()

2.强调:

  当你继承一个现有的类,并且你覆盖了父类的init方法时,必须在初始化方法的第一行调用父类的初始化方法,并传入父类所需的参数

组合

  也是一种关系,描述两个对象之间 是什么有什么的关系,例如,学生有手机 ,游戏中角色拥有某些装备

  将一个对象作为另一个对象的属性(既什么有什么)

1.组合的目的

  也是为了重用现有代码

  什么时候使用继承:分析两个类的关系,到底是不是什么是什么的关系

  什么时候使用组合:如果两个类之间,没有太大的关系,完全不属于同类

  另外组合相比继承,耦合度更低了

class Phone:
    def __init__(self,price,kind,color):
        self.price = price
        self.kind = kind
        self.color = color

    def call(self):
        print("正在呼叫XXXX;")

    def send_message(self):
        print("正在发送短信....")

class Student:
    def __init__(self,name,gender,phone):
        self.name = name
        self.gender = gender
        self.phone = phone

    def show_info(self):
        print("name:%s gender:%s" % (self.name,self.gender))

phone = Phone(1000,"apple","red")

stu1 = Student("rose","male",phone)
stu1.phone.call()
stu1.phone.send_message()
View Code

新式类与经典类

  python3中任何类都是直接或间接继承了Object

  新式类:任何显式或隐式地继承自object的类就称之为新式类, 所以python3中全都是新式类

  经典类:即不是object的子类 ,仅在python2中出现

菱形继承

因为python支持多继承,当出现了菱形继承时:

  如果是新式类,先深度,当遇到了共同父类时就广度

  如果是经典类,就是深度优先

猜你喜欢

转载自www.cnblogs.com/francis1/p/11247503.html