美文网首页
python基础-06-面向对象

python基础-06-面向对象

作者: 西海岸虎皮猫大人 | 来源:发表于2020-03-15 11:36 被阅读0次

1 概述

Python支持面向过程 | 面向对象 | 函数式编程等多种范式
面向对象编程是将数据和操作数据的方法封装到对象中
面向对象关注的是软件中对象之间的关系,适合大型程序
面向对象是宏观分解,底层仍是面向过程
面向对象,设计者思维;面向过程,执行者思维

软件行业,一个好的设计者必然也是一个好的执行者

解决问题: 面向对象思维统一中国
1.中国分为各阶级
2.解决各阶级间的关系

2 对象的进化

数据 -> 变多 -> 数组
数据 -> 类型变复杂 -> 结构体

struct resume{
    int age;
    char name[10];
    double salary;
};

数据 -> 逻辑变复杂 -> 对象
对象封装处理数据的方法

3 类定义 | 对象创建

类是制造对象的模具
类也是对象
对象的方法由同一类的所有对象共享

# 首字母大写,驼峰
class Student:
    # 构造函数,self必须位于第一个参数,存对象引用地址
    def __init__(self,name,score):
        self.name = name
        self.score = score

    def say_score(self):
        print('{0}的分数是{1}'.format(self.name,self.score))

s1 = Student('Vincent',99)
s1.say_score()

4 构造函数 - init

对象的value即属性和方法
普通方法第一个参数也是self
self相当于c++中的self指针,java\c#中的this

5 实例属性

从属于实例对象的属性

class Student:
    def __init__(self,name,age):
        ...

s1.age = 32
s1.salary = 3000

print(s1.age)

6 实例方法

从属于实例对象的方法

s2 = Student('Chris',100)
s2.say_score()
# 解释器执行实质,方法在类中,方法是共享的
Student.say_score(s2)
其他方法:

dir(obj)
获得对象的所有属性和方法
obj.dict
获得对象的属性字典
pass
空语句
isinstance(obj,Student)
判断对象是否是类的实例

7 类对象

class Student:
    pass

print(type(Student))
print(id(Student))

Stu2 = Student
s1 = Stu2()
print(s1)

8 类属性

从属于类对象,可以被所有对象共享

class Student:
    company = 'DFUN'
    count = 0

    def __init__(self, name, score):
        self.name = name
        self.score = score
        Student.count = Student.count + 1

    def say_score(self):
        print('公司{0},姓名{1},分数{2}'.format(Student.company, self.name, self.score))


s1 = Student('Vincent', 100)
s1.say_score()
s2 = Student('Chris', 99)
print(Student.count)
print(s1.count)

9 类方法 | 静态方法

类方法

从属于类对象的方法

# 类方法通过装饰器@classmethod定义
class Student:
    company = 'DFUN'

    @classmethod
    # 第一个参数cls必须有,代表类对象
    def printCompany(cls):
        print(cls.company)

Student.printCompany()
静态方法

与类对象无关的方法,不操作类属性

class Student:
    company = 'DFUN'
    
    @staticmethod
    def add(a,b):
        print(a+b)

Student.add(1,2)

说明:
类方法和静态方法中不能调用实例变量,实例方法

10 析构方法

释放对象占用的资源,如打开的文件\网络连接等
python自动垃圾回收机制(引用计数)调用del方法回收对象

class Person:
    def __del__(self):
        print('销毁对象')

p1 = Person()
p2 = Person()
del p2
print('程序结束')
# 打印程序结束后会调用p1的析构方法

11 call方法

定义了__call __方法的对象,则对象可以像函数一样调用,实际调用的是call方法
本质上a+b解释器执行的是对象的add方法

class SalaryCal:
    '''工资计算类'''
        
    def __call__(self,salary):
        print('计算工资...')
        yearSalary = salary*12
        daySalary = salary/22.5
        hourSalary = daySalary//8
        return dict(yearSalary=yearSalary,daySalary=daySalary,hourSalary=hourSalary)

s  = SalaryCount()
print(s(3000))

12 方法无重载 | 方法动态性

方法无重载

python中方法没有重载,是由于python中参数没有类型
参数数量也可以由可变参数控制

class Person:
    def say_hi(self):
        print('hello')
    # 只有第二个有效,第一个被覆盖
    def say_hi(self,name):
        print('hello,{0}'.format(name))
方法动态性
class Person:
    def work(self):
        print('努力工作')

def play(s):
    print('{0}在玩游戏'.format(s))

def work2(s):
    print('努力上班')

Person.play = play
p = Person()
p.work()
p.play('Vincent')
# 覆盖原有方法
Person.work = work2
p.work()

python中方法没有重载,是由于python中参数没有类型
参数数量也可以由可变参数控制

class Person:
    def say_hi(self):
        print('hello')
    # 只有第二个有效,第一个被覆盖
    def say_hi(self,name):
        print('hello,{0}'.format(name))
方法的动态性
class Person:
    def work(self):
        print('努力工作')

def play(s):
    print('{0}在玩游戏'.format(s))

def work2(s):
    print('努力上班')

Person.play = play
p = Person()
p.work()
p.play('Vincent')
# 覆盖原有方法
Person.work = work2
p.work()

13 私有属性

python对于类的成员没有严格的访问控制限制
1.通常约定,开头属性是私有的,其他为公共的
2.类内部可以访问私有属性\方法
3.类外部不能直接访问私有属性\方法
4.
类名
_私有属性\方法名,外部访问

# 测试私有属性
class Employee:
    def __init__(self,name,age):
        self.name = name
        self.__age = age

e = Employee('Vincent',18)
print(e.name)
# 私有属性外部不能直接访问,报错
# print(e.age)
print(e._Employee__age)

14 私有方法

class Employee:
    # 类变量也可以私有
    __company = 'DFUN'

     ...
    def __work():
        print('努力工作')
        # 类内部可以调用私有属性
        print(self.__age)

e = Employee('Vincent',18)
# 私有方法外部调用
e._Employee_work()
# 类外部调用私有类变量
print(Employee._Employee__company)

15 装饰器 | get set方法

@property

将一个方法调用变为属性调用

class Employee:
    @property
    def salary(self):
        print('salary')

emp = Employee()
print(emp.salary)
私有属性封装get\set方法
class Employee:

    def __init__(self,name,salary):
        # 私有属性
        self.__name = name
        self.__salary = salary

    def get_salary(self):
        return self.__salary

    def set_salary(self,salary):
        # 增加判断逻辑
        if 1000<salary<50000:
            self.__salary = salary
        else:
            print('录入错误')

emp = Employee('Vincent',18)
emp.set_salary(2000)
print(emp.get_salary())
使用@property封装get\set方法
class Employee:

    def __init__(self,name,salary):
        # 私有属性
        self.__name = name
        self.__salary = salary

    @property
    def salary(self):
        return self.__salary
    
    @salary.setter
    def set_salary(self,salary):
        # 增加判断逻辑
        if 1000<salary<50000:
            self.__salary = salary
        else:
            print('录入错误')

emp = Employee('Vincent',18)
emp.salary = 2000
print(emp.salary)

16 面向对象三大特性

封装 | 继承 | 多态

封装

隐藏细节如私有属性,只对外提供必要的方法
python没有严格的访问控制符语法,靠程序员自觉实现

继承

让子类具有父类特性,提高代码重用性
从设计上是一种增量进化

多态

同一方法调用由于调用对象不同产生不同的行为

17 继承

python支持多重继承
若没有指定父类,则默认父类是object

class Person:
    def __init__(self,name,age):
        self.name = name
        # 私有属性
        self.__age = age

    def say_age(self):
        print('年龄{}'.format(self.age))

class Student(Person):
    def __init__(self,name,age,score):
        # 调用父类构造方法,必须显示调用父类的构造方法
        Person.__init__(self,name,age)
        self.score = score

print(Student.mro())
s = Student()
# 子类调用父类方法
s.say_age()
print(s.name)
# 报错,父类私有属性可以被继承但不能直接用
# print(s.age)
print(s._Person__age)

18 方法重写

子类重新定义父类方法,将其覆盖

class Person:
    def __init__(self,name,age):
        self.name = name
        # 私有属性
        self.__age = age

    def say_age(self):
        print('年龄{}'.format(self.age))

    def say_introduce(self):
        print('我的名字是{}'.format(self.name))

class Student(Person):
    def __init__(self,name,age,score):
        # 调用父类构造方法,必须显示调用父类的构造方法
        Person.__init__(self,name,age)
        self.score = score
    # 重写父类方法
    def say_introduce(self):
        print('报告老师,我的名字是{}'.format(self.name))

s = Student('Vincent',18,100)
s.say_introduce()

19 根类 - object

mro()

查看类的继承层次结构

object根类
obj = object()
# 查看对象属性
print(dir(obj))

20 重写str方法

class Person:
    def __init__(self,name,age):
        self.name = name
    
    def __str__(self):
        return '名字是{}'.format(self.name)

p = Person('Vincent')
print(p)

21 多重继承

python支持多重继承,但会使类层次结构变复杂,尽量避免使用

class A:
    def aa(self):
        print('aa')

class B:
    def bb(self):
        print('bb')

class C(A,B):
     def cc(self):
        print('cc')

c = C()
c.aa()
c.bb()
c.cc()

22 多继承父类方法重名 - mro

当多继承时,不同父类具有同名方法,按照从左到右的顺序执行

23 获取父类定义 - super

class A:
    def say(self):
        print('A',self)

 class B(A):
     def say(self):
       # A.say()
        super.say()
        print('B',self)

B().say

23 多态

多态
同一方法调用由于对象不同产生不同行为
两个必要条件:继承\方法重写

class Man:
    def eat(self):
        print('吃饭')

class Chinese(Man):
    def eat(self):
        print('中国人吃饭')

class English(Man):
    def eat(self):
        print('英国人吃饭')

def manEat(m):
    if isinstance(m,Man):
        m.eat()
    else:
        print('不能吃饭')

manEat(Chinese())
manEat(English())

25 运算符重载

python运算符实质是调用对象的特殊方法实现
每个运算符实质都对应了相应的方法
字符串乘法实际是调用了_mul_

a = 10
b = 20
c = a.__add__(b)
常见特殊方法

_init_
_del_

测试-重写add方法
class Person:
    def __init__(self,name):
      self.name = name
    # 同理可定义__mul__乘法运算
    def __add__(self,other):
        if isinstance(other,Person):
            return '{}--{}'.format(self.name,other.name)
        else:
            return '不是同类对象'

p1 = Person('Vincent')
p2 = Person('Chris')
x = p1 + p2
print(x)

26 特殊属性

_class_ 对象所属类
_bases_ 基类元组
_base_ 基类

class A:
    def a(self):
        print('aa')

a = A()
print(a.__dict__)
print(a.__class__)
# 父类列表
print(A.__bases__)
# 类的继承结构
print(a.mro())
# 子类列表
print(A.__subclasses__)

27 对象浅拷贝 | 深拷贝

根据是否拷贝对象的子对象区分深浅
python拷贝一般都是浅拷贝
深拷贝通过copy的deepcopy函数实现

import copy

# 测试对象的深浅拷贝
class MobilePhone:
     def __init__(self,cpu,screen):
        self.cpu = cpu
        self.screen = screen
class CPU:
    def cal(self):
        print('计算')
class Screen:
    def show(self):
        print('显示')

c1 = CPU()
# c2\c1指向同一对象
c2 = c1
print(c1)
print(c2)

s1 = Screen()

# 测试浅复制
m1 = MobilePhone(c1,s1)
m2 = copy.copy(m1)
# 浅复制子对象相同
print(m1,m1.cpu,m1.screen)
print(m2,m2.cpu,m2.screen)
# 测试深复制
m3 = copy.deepcopy(m1)
# 深复制子对象不同
print(m3,m2.cpu,m2.screen)

28 组合

is-a 继承
has-a 组合,如手机有CPU

class A1:
    def say(self):
        print('a1')

class B1(A1):

b1 = B1()
# 继承方式实现代码复用
b1.say()

class A2:
    def say(self):
      print('a2')

class B2:
    def __init__(self,a)
        self.a = a

a2 = A2()
b2 = B2(a2)
# 组合方式实现代码复用
b2.a.say()    

29 设计模式-工厂模式

实现调用者与实现者的分离
设计模式实质就是分离
规模越大的软件越需要设计模式

class CarFactory:
    def createCar(self,brand):
        if brand == '奔驰'
            return Benz()
        elif brand == '宝马'
            return BMW()
        elif brand == '比亚迪'
            return BYD()
        else:
            return '位置品牌'
class Benz:
    pass

class BMW:
    pass

class BYD:
    pass

fac = CarFactory()
c1 = fac.createCar('奔驰')
c2 = fac.createCar('比亚迪')
print(c1)
print(c2)

30 设计模式-单例模式

单例模式

确保一个类只有一个实例,提供一个访问该实例的全局访问点
降低开销

# 测试单例模式
class MySingleton:
    __obj = None
    __init_flag = True
  
    def __new__(cls,*args,**kargs):
        if cls.__obj == None:
            cls.__ojb = object.__new__(cls)
        return cls.__obj

    def __init__(self,name):
        # 保证初始化方法只被调用一次
        if MySingleton.__init_flag:
          print('init...')
          self.name = name
          MySingleton.__init_flag = False

a = MySingleton('aa')
b = MySingleton('bb')
# a\b为同一对象
print(a)
print(b)

练习: 整合工厂 | 单例

相关文章

  • python基础-06-面向对象

    1 概述 Python支持面向过程 | 面向对象 | 函数式编程等多种范式面向对象编程是将数据和操作数据的方法封装...

  • python面向对象学习笔记-01

    学习笔记 # 0,OOP-Python面向对象 - Python的面向对象 - 面向对象编程 - 基础 -...

  • Python OOP-1

    0. OOP-Python面向对象 Python面向对象 面向对象编程基础公有私有继承组合,Mixin 魔法函数魔...

  • python的面向对象

    python的面向对象(ObjectOriented,OO)-面向对象编程-基础-公有私有-继承-组合,Minxi...

  • 001-python知识

    Python基础 一、Python的基本概念 (一)面向对象 Python是一门面向对象的语言,像C语言和GO语言...

  • Python面向对象(基础)

    面向对象 Python是支持面向对象的,面向对象编程是一种程序设计思想。 类和实例(基础) 面向对象最重要的就是类...

  • 【知识详解】JAVA基础(秋招总结)

    JAVA基础 目录 JAVA基础 问:面向过程(POP)和面向对象(OOP)? 问:Python和Java的区别?...

  • 面向Python,面向对象(基础)!

    简单、易学、免费、开源、高层语言、可移植性、解释性、面向对象、可拓展性、丰富的库、规范的代码等。 缺点: 运行速度...

  • Python 入门笔记

    1.Linux基础 2.Python基础 3.Python面向对象 4.项目实战 励志公式 1.01365=...

  • 黑马上海37期Python全套视频课程

    python基础班 1-1 Linux基础 1-2 python基础 1-3 面向对象 1-4 项目飞机大...

网友评论

      本文标题:python基础-06-面向对象

      本文链接:https://www.haomeiwen.com/subject/tnqcehtx.html