Pytho面向对象进阶

Python面向对象方法的进阶

    • 方法没有重载
    • 方法的动态性的测试
    • 私有属性和私有方法(实现封装)
    • @property 装饰器
    • 类编码风格
    • 面向对象三大特征介绍
    • 继承
    • 类成员的继承和重写
    • mro()
    • dir()查看对象属性
    • __str__()方法
    • 多重继承
    • super()获得父类定义
    • 多态
    • 特殊方法和运算符重载
    • 特殊属性
    • 对象的浅拷贝和深拷贝
      • 变量的赋值操作
      • 浅拷贝
      • 深拷贝
    • 组合
    • 设计模式_工厂模式实现
      • 工厂模式
      • 单例模式

方法没有重载

方法签名包含 3个部分:方法名、参数数量、参数类型。
python 中,类体方法的的参数没有声明类型(调用时确定参数的类型),参数的数量也可以由可变参数控制。如果我们在类体中定义了多个重名的方法,只有最后一个方法有效

#测试python中重命名方法
class mytype():
    def say_hi(self,name):
        print('你好')
    def say_hi(self,name):
        print('{0}你好呀'.format(name))
p1=mytype()
p1.say_hi('孙悟空')

建议:不要使用重名的方法!Python 中方法没有重载。

方法的动态性的测试

Python 是动态语言,我们可以动态的为类添加新的方法,或者动态的修改类的已有的方法。

#方法的动态性
class Mytype:
    def work(self):
        print('好好学习')

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

def work1(s):
    print('你好')
P=Mytype()
Mytype.work= work1
Mytype.play=play
P.work()
P.play()

私有属性和私有方法(实现封装)

Python 对于类的成员没有严格的访问控制限制,这与其他面向对象语言有区别。关于私有
属性和私有方法,有如下要点:
(1). 通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。
(2). 类内部可以访问私有属性(方法)
(3). 类外部不能直接访问私有属性(方法)
(4). 类外部可以通过“_类名__私有属性(方法)名”访问私有属性(方法)

#私有属性和方法的测试
class Sea:
    __Area=10000
    def __init__(self,name,volume):
        self.name=name
        self.__volume=volume
    def say_Sea(self):
        print("海洋的面积是{0}".format(Sea.__Area))
        print("{0}的体积是{1}".format(self.name,self.__volume))

P1=Sea('太平洋',1200)
print(P1.name)
print(dir(P1))
P1.say_Sea()
print(P1._Sea__volume) #**注意格式问题Sea后无右下角的点**

@property 装饰器

property即是属性的意思
@property 可以将一个方法的调用方式变成“属性调用”。
装饰器的使用方法

#property装饰器的使用
class employee:
    @property
    def say_salary(self):
        print('夏明的薪资很多')
        return 1000

P1=employee()
#P1.say_salary()
print(P1.say_salary)

打印薪资

#property的使用方法
class employee:
    def __init__(self,name,salary):
        self.__name=name
        self.__salary=salary
    @property
    def salary(self):
        return self.__salary

    @salary.setter
    def salary(self,salary):
        if 1000<salary<50000:
            self.__salary=salary
        else:
            print('录入错误,请重新输入')


P1=employee('悟空',10000)
P1.salary=-3000
P1.salary=3000
print(P1.salary)
P1.salary=4000
print(P1.salary)

类编码风格

(1). 类名首字母大写,多个单词之间采用驼峰原则。
(2). 实例名、模块名采用小写,多个单词之间采用下划线隔开。
(3). 每个类,应紧跟“文档字符串”,说明这个类的作用。
(4). 可以用空行组织代码,但不能滥用。在类中,使用一个空行隔开方法;模块中,使用两个空行隔开多个类。

面向对象三大特征介绍

(1)封装(隐藏);(2)继承; (3)多态

继承

如果一个新类继承自一个设计好的类,就直接具备了已有类的特征,就大大降低了工作难度。已有的类,我们称为“父类或者基类”,新的类,我们称为“子类或者派生类”。
Python 支持多重继承,一个子类可以继承多个父类。

#继承的方法测试

class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def say_age(self):
        print(self.name,'的年龄是',self.age)
class Student(Person):
    def __init__(self,name,age,score):
        Person.__init__(self,name,age)
        self.score=score

s=Student('悟空',80,30)
s.say_age()
print(s.name)
print(Person.mro())
print(Student.mro())

类成员的继承和重写

(1). 成员继承:子类继承了父类除构造方法之外的所有成员。
(2). 方法重写:子类可以重新定义父类中的方法,这样就会覆盖父类的方法,也称为“重写”.

#继承和方法重写
class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def say_age(self):
        print(self.name,'的年龄是',self.age)
    def say_name(self):
        print('我的名字是{0}'.format(self.name))
class Student(Person):
    def __init__(self,name,age,score):
        Person.__init__(self,name,age)
        self.score=score
    def say_name(self):
        print('大家好,我的名字是{0}'.format(self.name))

s=Student('悟空',80,30)
s.say_age()
s.say_name()

mro()

通过类的方法 mro()或者类的属性__mro__可以输出这个类的继承层次结构。

#类的层次结构
class A:
    pass
class B(A):
    pass
class C(B):
    pass
print(C.mro())

dir()查看对象属性

内置函数 dir(),它可以方便的看到指定对象所有的属性。

str()方法

object 有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数 str()经常用于 print()方法,帮助我们查看对象的信息str()可以重写。

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

    def __str__(self):
        return '我的的名字是{0}'.format(self.name)
s=Person('悟空')
print(s)
print(dir(s))

多重继承

Python 支持多重继承,一个子类可以有多个“直接父类”。这样,就具备了“多个父类”的特点。但是由于,这样会被“类的整体层次”搞的异常复杂,尽量避免使用。

Python 支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将**“从左向右”**按顺序搜索。

super()获得父类定义

在子类中,如果想要获得父类的方法时,我们可以通过 super()来做,super()代表父类的定义,不是父类对象。

#super()方法的使用
class A:
    def say_a(self):
        print('你好,悟空')
        print('你好,八戒')
class B(A):
    def say_b(self):
        super().say_a()  #调用父类A中的方法
        print('你好,悟净')
s=B()
s.say_b()  #此时A中的方法也会被调用

多态

多态(polymorphism)是指同一个方法调用由于对象不同可能会产生不同的行为。关于多态要注意以下 2 点:
(1). 多态是方法的多态,属性没有多态。
(2). 多态的存在有 2 个必要条件:继承、方法重写。

#多态的使用
class Animal:
    def shout(self):
        print('动物叫了一声')
class Cat(Animal):
    def shout(self):
        print('小猫喵喵')
class Dog(Animal):
    def shout(self):
        print("小狗汪汪")
class Fly:
    def shout(self):
        print("苍蝇嗡嗡")
def Animalshout(a):
    if isinstance(a,Animal):
        a.shout()
    else:
        print('乱吼一通')
Animalshout(Dog())
Animalshout(Cat())
Animalshout(Fly())

特殊方法和运算符重载

Python 的运算符实际上是通过调用对象的特殊方法实现的

#运算符的重载
class Person:
    def __init__(self,name):
        self.name=name
    def __add__(self,other):
        if isinstance(other,Person):
            return '{0}+{1}'.format(self.name,other.name)
        else:
            print('不是同类对象不能相加')

    def __mul__(self, other):
        if isinstance(other, int):
            return self.name * other
        else:
            return "不是同类对象, 不能相乘"
x1=Person('悟空')
x2=Person('八戒')
x3=Person('悟净')
y=x2+x3
s=x1+x2
print(s)
print(y)
print(x1*4)

特殊属性

Python 对象中包含了很多双下划线开始和结束的属性,这些是特殊属性,有特殊用法。

#测试特殊属性
class A:
    pass
class B:
    pass
class C(B,A):
    def __init__(self,nn):
        self.nn = nn
    def cc(self):
         print("cc")
c = C(3)
print(dir(c))  #查看对象属性
print(c.__dict__)  # 对象的属性字典
print(c.__class__)  # 对象属性的类
print(C.__bases__)  # 类的基类元组(多重继承)
print(C.__base__) #类的基类
print(C.mro())   # 类的层次结构
print(A.__subclasses__())  #子类列表

对象的浅拷贝和深拷贝

变量的赋值操作

只是形成两个变量,实际还是指向同一个对象。

浅拷贝

Python 拷贝一般都是浅拷贝。拷贝时,对象包含的子对象内容不拷贝。因此,源对象和拷贝对象会引用同一个子对象。

深拷贝

使用 copy 模块的 deepcopy 函数,递归拷贝对象中包含的子对象。源对象和拷贝对象所有的子对象也不同

#测试深拷贝和浅拷贝
import copy
class MobilePhone:
    def __init__(self,cpu,screen):
        self.cpu=cpu
        self.screen=screen

class CPU:
    def show_CPU(self):
        print('CPU是核心处理器')
class Screen:
    def show_Screen(self):
        print('Screen是显示器')

#测试变量赋值
c=CPU()
c1=c
print(c1)
print(c)

#测试浅复制
print('测试浅复制')
s=Screen()
m1=MobilePhone(s,c)
m2=copy.copy(m1)
print(m1,m2)
print(m1.screen,m2.screen)
#测试深复制
print('测试深复制')
m3=copy.deepcopy(m1)
print(m1,m3)
print(m1.screen,m3.screen)

组合

“is-a”关系,我们可以使用“继承”。从而实现子类拥有的父类的方法和属性。“is-a”
关系指的是类似这样的关系:狗是动物,dog is animal。狗类就应该继承动物类。
“has-a”关系,我们可以使用“组合”,也能实现一个类拥有另一个类的方法和属性。”
has-a”关系指的是这样的关系:手机拥有 CPU。 MobilePhone has a CPU。

#测试继承
class MobilePhone:
    def say_Phone1(self):
        print('手机拥有处理器')
    def say_Phone2(self):
        print('手机拥有显示器')

class CPU(MobilePhone):
    pass
c=CPU()
c.say_Phone1()

#测试组合
class Screen:
    def __init__(self, a):
        self.a = a
m=MobilePhone()
s=Screen(m)
s.a.say_Phone2

设计模式_工厂模式实现

对于初学者,学习两个最常用的模式:工厂模式和单例模式

工厂模式

工厂模式实现了创建者和调用者的分离,使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制。

单例模式

单例模式(Singleton Pattern)的核心作用是确保一个类只有一个实例,并且提供一个访问该实例的全局访问点。

你可能感兴趣的:(python,python)