从0开始学python_面向对象进阶

从0开始学python_面向对象进阶

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

Python 对于类的成员没有严格的访问控制限制,这与其他面向对象语言有区别。关于私有 属性和私有方法,有如下要点:

  1. 通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。 2. 类内部可以访问私有属性(方法)
  2. 类外部不能直接访问私有属性(方法)
  3. 类外部可以通过“_类名__私有属性(方法)名”访问私有属性(方法)
#测试私有属性

class Employee:

    def __init__(self,name,age):
        self.name=name
        self.__age=age

e=Employee('高淇',18)

print(e.name)
#print(e.age)
print(e._Employee__age)
print(dir(e))

@property 装饰器:

@property 可以将一个方法的调用方式变成“属性调用”。下面是一个简单的示例,让大 家体会一下这种转变:

#@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('录入错误,薪水在1000-50000之间')
emp1=Employee('高淇',30000)
print(emp1.salary)
emp1.salary=2000
print(emp1.salary)

#不用装饰器时的用法
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('录入错误,薪水在1000-50000之间')

emp1=Employee('高淇',10000)
print(emp1.get_salary())
emp1.set_salary(5000)
print(emp1.get_salary())

@property 主要用于帮助我们处理属性的读操作、写操作。对于某一个属性,我们可以直 接通过:
emp1.salary = 30000 如上的操作读操作、写操作。但是,这种做法不安全。比如,我需要限制薪水必须为 1-10000 的数字。这时候,我们就需要通过 getter、setter 方法来处理。

属性和方法命名总结
· _xxx:保护成员,不能用“from module import * ”导入,只有类对象和子类对象能访 问这些成员。
· xxx:系统定义的特殊成员
· __xxx: 类中的私有成员,只有类对象自己能访问,子类对象也不能访问。(但,在类外 部可以通过“对象名. _类名__xxx”(e._Employee__age)这种特殊方式访问。Python 不存在严格意义的私有成员)
注:再次强调,方法和属性都遵循上面的规则。

**

面向对象三大特征介绍

**
Python 是面向对象的语言,也支持面向对象编程的三大特性:继承、封装(隐藏)、多态。
·封装(隐藏)
隐藏对象的属性和实现细节,只对外提供必要的方法。相当于将“细节封装起来”,只 对外暴露“相关调用方法”。
通过前面学习的“私有属性、私有方法”的方式,实现“封装”。Python 追求简洁的 语法,没有严格的语法级别的“访问控制符”,更多的是依靠程序员自觉实现。
·继承
继承可以让子类具有父类的特性,提高了代码的重用性。
从设计上是一种增量进化,原有父类设计不变的情况下,可以增加新的功能,或者改进 已有的算法。
·多态
多态是指同一个方法调用由于对象不同会产生不同的行为。生活中这样的例子比比皆 是:同样是休息方法,人不同休息方法不同。张三休息是睡觉,李四休息是玩游戏,程序员休息是“敲几行代码”。

继承:
继承是面向对象程序设计的重要特征,也是实现“代码复用”的重要手段。
如果一个新类继承自一个设计好的类,就直接具备了已有类的特征,就大大降低了工作 难度。已有的类,我们称为“父类或者基类”,新的类,我们称为“子类或者派生类”。

#测试继承的基本属性

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

    def say_age(self):
        print('年龄,年龄,我也不知道')

class Student(Person):
    def __init__(self,name,age,score):
        Person.__init__(self,name,age) #调用父类的属性
        self.score=score

#Student-->Person-->object类
print(Student.mro())

s=Student('高淇',18,80)
s.say_age()
print(s.name)
#print(s.age) 子类不能直接调用父类的私有属性
print(dir(s))
print(s._Person__age) #这样调用私有属性就可以了

方法重写:

#方法的重写

class Person:

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

    def say_age(self):
        print('我的年龄:',self.__age)

    def say_introduce(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_introduce(self):
        #重写了父类的方法
        print('报告老师,我的名字是:{0}'.format(self.name))

s=Student('高淇',18,80)
s.say_age()
s.say_introduce()

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

#测试重写object的__str__()

class Person:   #默认继承object类

    def __init__(self,name):
        self.name=name

    def __str__(self):
        return '名字是:{0}'.format(self.name)

p=Person('高淇')
print(p)

多重继承
Python 支持多重继承,一个子类可以有多个“直接父类”。这样,就具备了“多个父 类”的特点。但是由于,这样会被“类的整体层次”搞的异常复杂,尽量避免使用。
MRO()
Python 支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将 “从左向右”按顺序搜索。

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

#测试super(),代表父类的定义,而不是父类的对象

class A:

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

class B(A):

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

B().say

多态
多态(polymorphism)是指同一个方法调用由于对象不同可能会产生不同的行为。在现实 生活中,我们有很多例子。比如:同样是调用人的休息方法,张三的休息是睡觉,李四的休 息是玩游戏,高淇老师是敲代码。同样是吃饭的方法,中国人用筷子吃饭,英国人用刀叉吃 饭,印度人用手吃饭。
关于多态要注意以下 2 点:

  1. 多态是方法的多态,属性没有多态。
  2. 多态的存在有 2 个必要条件:继承、方法重写。
#多态

class Man:
    def eat(self):
        print('饿了,吃饭啦!')

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

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

class Indian(Man):
    def eat(self):
        print('印度人用右手吃饭')

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

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

运算符重载:

#运算符重载
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:
            return'不是同类对象,不能相加'
    def __mul__(self,other):
        if isinstance(other,int):
            return self.name*other
        else:
            return'不是同类对象,不能相乘'

p1=Person('高淇')
p2=Person('高希希')

x=p1+p2
print(x)

print(p1*3)

运算结果:
高淇–高希希
高淇高淇高淇

特殊属性:
Python 对象中包含了很多双下划线开始和结束的属性,这些是特殊属性,有特殊用法。这 里我们列出常见的特殊属性:
在这里插入图片描述
继承和组合:

#测试has-a关系,使用组合

class MobilePhone:
    def __init__(self,cpu,screen):
        self.cpu=cpu
        self.screen=screen

class CPU:
    def calculate(self):
        print('算你个12345')
        print('cpu对象:',self)

class Screen:
    def show(self):
        print('显示一个好看的画面,亮瞎你的钛合金大眼')
        print('screen对象:',self)

m=MobilePhone(CPU(),Screen())
m.cpu.calculate()
m.screen.show()

工厂模式:

#测试工厂模式

class CarFactory:
    def creat_car(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

factory=CarFactory()
c1=factory.creat_car('奔驰')
c2=factory.creat_car('比亚迪')
print(c1)
print(c2)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值