Python基础知识之面向对象

21 篇文章 0 订阅
1 篇文章 0 订阅

六、面向对象

(一)面向过程

定义:分析解决问题的步骤,然后逐步实现

公式:程序=算法+数据结构

(二)基本内容

1.定义

找出解决问题的人,然后分配职责

2.公式

程序=对象+交互

3.思想 ​ 识别对象,找人 ​ 分配职责,干活 ​ 建立交互,调用

 

class computer:
    #数据成员
    def __init__(self,brand_name,cpu_model,color):
        #self 是调用当前方法的对象地址
        self.brand_name = brand_name
        self.cpu_model = cpu_model
        self.color = color
    #方法成员
    def print_information(self):
        """
        打印产品信息
        :return:
        """
        print("电脑品牌是{},颜色是:{},cpu型号是            {},".format(self.brand_name,self.color,self.cpu_model))
    def open_computer(self):
        """
        启动电脑
        :return:
        """
        print("正在开机")
#创建对象,实际在调用__init__方法
com01 = computer("戴尔","黑色","inter_ci5")
com01.print_information()
com01.open_computer()
com01 = computer("联想","黑色","inter_ci511")
com01.print_information()
com01.open_computer()

(三)具体内容

  • 类 class -

定义:一个抽象的概念,如动物、人类

格式:类名所有单词首字母大写

——init—— 构造函数,创建对象时被调用

组成:

数据 (数据不同,类可能相同)

方法(方法不通,则类不同)

  • 对象

定义 ​ 类的实体

  • 实例变量与实例方法

"""
实例变量      
​
调用  print(对象.<变量>) 
    对象.<变量> =    #修改
​
实例方法
    def <>(self,参数列表):
      方法体
    调用:对象.<>
    作用:操作实例的数据
"""
​
class Person:   #类
    def __init__(self,name,age):    #数据成员
        self.name = name
        self.age = age
    def eat(self):     #方法
        print("{}吃了饭".format(self.name))
     
​
name = "刘亦菲"
age = 32
peo = Person(name,age)  #对象   具体的事物
peo.age = 31   #修改
peo.eat()

注:

对象:类的具体事例,即归属于某个类别的个体,(具体的事物)

类是创建对象的模板。

--数据成员(变量):名词类型的状态。

--方法成员(函数):动词类型的行为

  • 类变量与类方法

含义:

类变量 描述所有对象的共有数据

类方法 用于操作类变量

语法

"""
定义:
 class <>:      #在类中,方法外定义变量
        变量名 = 表达式    #数据
        
        @classmethod
        def <>(cls,参数列表):   #方法
            方法体
​
调用:
类名.变量名
类名.<方法名>
"""
class Beauty:
    count =0  #类变量,统计人数
    def __init__(self,name,age):
        self.name = name
        self.age = age
        Beauty.count += 1 #类变量必须用类调用
    @classmethod
    def print_count(cls):
        print("共有%d个人"%Beauty.count)
​
beauty1 = Beauty("刘亦菲",32)
beauty2 =Beauty("貂蝉",19)
Beauty.print_count()  #2人
  • 静态方法

    既不操作类变量,也不操作实例变量,将函数引入类中,就不需要加self

    """
    语法
    定义
    @staticmethod
    def <>():
         方法体
         
    调用
    类名.方法名()
    """
    #二维向量
    lists = [
        ["00","01","02","03"],
        ["10","11","12","13"],
        ["20","21","22","23"],
        ["30","31","32","33"],
    ]
    ​
    class Vector:
        "坐标"
        def __init__(self,x,y):
            self.x = x
            self.y = y
        @staticmethod   #静态方法
        def up(self):#上移
            return (-1,0)
        def down(self):#下移
            return (1,0)
        def right(self):#上移
            return (0,1)
        def left(self):#上移
            return (0,-1)
        
    class VectorHelper:
        def __init__(self,lists):
            self.lists = lists
        def get_elements(self,place,vect_dice,count):
            """
            place  位置坐标
            vect_dice   位移方向
            count     距离
            """
            list_temp = []
            for i in range(count):
                place.x += vect_dice.x
                place.y += vect_dice.y
                list_temp.append(self.lists[place.x][place.y])
             
            print(list_temp)
    helper = VectorHelper(lists)
    helper.get_elements(Vector(0,2),Vector.down,2) 

(四)特性

1.封装

(1)定义

从数据角度讲,将基本数据复合成一个自定义类型 从行为讲,向类外提供必要的功能,隐藏实现的细节 从设计角度,分而治之,变则疏之(变化点独立封装),高内聚(单任务),低耦合

(2)私有成员

作用:无需向类外提供的成员,可以通过私有化进行屏蔽 方法:命名使用双下划线开头(数据和方法都可用) 本质 用将变量名<> 改为_类名__<> 来混淆

#封装的过度版1
class Person:
    def __init__(self,name,age):
        self.name = name
        self.__age = age
    def show_age(self):
        return self.__age
    def update_age(self,age):
        if 0<=age<=100:
            self.age = age
        else:
            raise ValueError("age的范围不对")
​
w01 = Person("")
​
w01.age =100  #则无法进行修改,因为属性  已隐藏
​
w01._Wife__age = 100 #需使用此格式来修改
​
<变量>.__dict__()  可以以字典的形式查看     

(3)属性@property

使用私有成员方法封装

只写或只读 <变量> = property(None,<写>) ​ <变量> = property(<读>,None)

"""
过度版2
语法:使用property(<读取方法>,<写入方法>)  
"""
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    age = property(__show_age,__updata_age)  #property属性,负责拦截读写操作
    #property(None,updata_age)    只能写
    #property(None,updata_age)    只能读
    def __show_age(self):
        return self.__age
    def __update_age(self,age):
        if 0<=age<=100:
            self.__age = age
        else:
            raise ValueError("age的范围不对")
​
w01 = Person("刘亦菲",32)
w01.age = 33
终极版

"""
定义
    @property  #只负责拦截读
    def <name>(self):
        return self.__name
    @name.setter #只负责拦截写入操作
        def <name>(self.name):
            self.__name = name
调用
    对象.属性 = 数据
    变量 = 队形.属性名
"""
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        
    @property
    def age(self):    
        return self.__age
    
    @age.setter
    def age(self,age):
        if 0<=age<=100:
            self.__age = age
        else:
            raise ValueError("age的范围不对")
​
w01 = Person("刘亦菲",32)
w01.age = 33

2.继承

(1)性质

子类之间可以相互调用,子类也可以调用父类成员,父类对象只可以调用父类成员

多个子类在概念上一致的,所以就抽象出一个父类;

多个子类的共性,可以提取到父类中,

在实际开发中:

从设计角度:先有子,再有父

从编码角度:先有父,再有子

价值-----父类隔离子类的变化,规范子类

(2)组成

变量

子类若没有构造函数,则使用父类的构造函数(init); ​ 子类若具有构造函数,则必须先调用父类

子类通过super(). __ init __()调用父类参数

子类可以调用父类的方法

方法-----子类可以调用父类的方法

class Person:
​
    def __init__(self.name):
​
        self.name = name
​
​
class Student(Person):
​
    def __init__(self,name,score):
​
        super().__init__(name)
        self.score = score
        
 
per = Person()
stu = Student()
#判断对象是否属于一个类型
print(isinstance(per,Person)) #True
#判断一个类型是否属于另一个类
print(issubclass(Student,Person)) #True

3.多态

定义 ​ 父类的同一种动作或者行为,在不同的子类有不同的实现 ​ 调用父,执行子

4.设计原则

开-闭原则(目标)

对扩展开放,对修改关闭

增加新功能,不改变原有代码

类的单一职责(类的定义) 依赖倒置(依赖抽象)

客户端代码(调用的类,使用者)尽量(使用)抽象的组件(做一个父类-继承)。抽象的是稳定;实现是多变

组合复用原则 复用的最佳实践 里氏替代- 迪米特法则

 

#图形管理器
class GraphicalManager:
    def __init__(self):
        self.__graph_list = []
    def insert_graph(self,graph):
        if isinstance(graph,Graphical): #判断对象graph是否属于Graphical类
            self.__graph_list.append(graph)
        else:
            raise ValueError()
    def sum_area(self): #计算所有图形的面积和
        result = 0
        for item in self.__graph_list:
            result += item.calcu_area()
        return result
            
class Graphical:  #图形
    #父类太过于抽象,无法写出方法体
    def calcu_area(self):
        #若子类不重写,则报错
        raise NotImplementedError()
        
class Square(Graphical):
    def __init__(self,length,wide):
        self.length = length
        self.wide = wide
    def calcu_area(self):
        return self.length * self.wide
    
    
squ=Square(4,5)
manager = GraphicalManager()
manager.insert_graph(squ)
print(manager.sum_area)

5.类与类的关系

泛化(继承) b类继承a类 关联(组合) a类中包含B类成员 作用域整个类 依赖 b类作为a类中方法的参数 作用域一个方法

 

#员工管理器
class StaffManager:
    def __init__(self):
        self.__staff_lists=[]  #员工列表
    
    def insert(self,staff):  #将员工添加到列表
        if isinstance(staff,Staff):
            self.__staff_lists.append(staff)
        else:
            raise ValueError()
     def sum_salary(self):    #计算员工工资和
        result = 0
        for item in self.__staff_lists:
            result += item.calcu_salary()
        return result
    
    
#员工
class Staff:
    def __init__(self,salary):  #员工基础工资
        self.salary = salary
    def calcu_salary(self):
        raise NotImplementedError()
​
class Programmer(Staff):
    def __init__(self,salary,project_salary):#基础工资+项目分红
        super(). __ init __(salary)
        self.project_salary=project_salary
        
    def calcu_salary(self):
        return self.salary+ self.project_salary

6.常见内置函数

isinstance(<对象>,类) 判断对象是否是一个类型,返回true,flase issubclass((<类>,父类) 判断一个类型是否属于另一个类型 type() 可以判断类型 内置可重写函数 以双下划线开头,双下划线结尾 __ str __ ()函数 将对象转化为字符串(对人友好) __ repr __ () 将对象转化为字符串(解释器可识别)

class Stu:
    def __init__(self,name,sex):
        self.name = name
        self.sex = sex
    
    def __str__(self):#任意格式
        return "{}{}".format(name,sex)
    
    def __repr_(self): #有固定的格式
        return "Stu({},{})".format(name,sex)
    
stu = Stu("林妹妹","女")
print(stu)
stu1 = repr(stu)  #克隆对象
eval(stu1)    # stu对象   Stu("林妹妹","女")

7.运算符重载

(1)定义

让自定义生成的对象能够使用运算符

(2) 类型

算数运载符重载------格式:对象 +数字

 

反向算数运载符重载 ------格式:对象 +数字

 

class Vector:
    def __init__(self,x):
        self.x = x
  
    def __add__(self, other):  #算数运载符重载
​
        return Vector(self.x+other)
​
    def __sub__(self, other):
​
        return Vector(self.x - other)
​
    def __mul__(self, other):
​
        return Vector(self.x * other)
    
    def __radd__(self, other):  #反向算数运载符
​
        return Vector(other+self.x)
​

复合运载符重载

 

比较运载符重载

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨非墨Lg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值