21 面向对象

21 面向对象

1 类的基本模型

面向对象
类名:用驼峰式命名,首字母必须大写

class 类名:
    特征: 属性
    动作:  方法

实例,对象
huawei = Phone()
huawei.price = 5999

2 类的类方法和静态方法

'''
 特点:
  1. 定义需要依赖装饰器@classmethod
  2. 类方法中参数不是一个对象,而是类
     print(cls)  # <class '__main__.Dog'>
  3. 类方法中只可以使用类属性,不能使用类方法属性
  4. 类方法中可否使用普通方法?  不能使用类的普通方法

类方法作用:
因为只能访问类属性和类方法,所以可以在对象创建之前,如果需要完成一些动作(功能)
'''
class Dog:
    color = "白色"

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

    def run(self):  # self   对象
        print('{}在院子里跑来跑去!'.format(self.nickname))

    def eat(self):
        print('吃饭。。。。。')
        self.run()  # 类中方法的调用,需要通过self.方法名()

    @classmethod
    def test(cls):  # cls  class
        print('----------')
        print(cls)  # <class '__main__.Dog'>
        # cls.run()   # 报错
        print(cls.nickname) # AttributeError: type object 'Dog' has no attribute 'nickname'
        print(cls.color)   # 报错
        # print(self.nickname)    # 报错 NameError: name 'self' is not defined

Dog.test()

d = Dog('大黄')
d.run()  # 调用run
d.test()



'''
静态方法: 很类似类方法
1. 需要装饰器@staticmethod
2. 静态方法是无需传递参数(cls,self)
3. 也只能访问类的属性和方法,对象的是无法访问的
4. 加载时机同类方法
'''
class Person:
    __age = 18

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

    def show(self):
        print('--------->', self.__age)

    @classmethod
    def update_age(cls):
        cls.__age = 20
        print('----------->类方法')

    @classmethod
    def show_age(cls):
        print('修改后的年龄是:', cls.__age)

    @staticmethod
    def test():
        print('---------->静态方法')
        print(Person.__age)

Person.update_age()
Person.show_age()
Person.test()


总结:
类方法  静态方法
不同:
  1. 装饰器不同 @classmethod  @staticmethod
  2. 类方法是有(cls)参数的,静态方法没有(self,cls)参数

相同:
  1. 只能访问类的属性和方法,函数对象的是无法访问的
  2. 都可以通过类名调用访问
  3. 都可以在创建对象之前使用,因为是不依赖于对象

普通方法 与 两者区别:
不同:
   1. 没有装饰器
   2. 普通方法永远是要依赖对象,因为每个普通方法都有一个self
   3. 只有创建了对象才可以调用普通方法,否则无法调用。

3 类的魔法方法

魔术方法
__init__:初始化魔术方法      作用:构造方法,创建完空间之后调用的第一个方法
触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)

__new__: 实例化的魔术方法    作用:开辟空间  
触发时机: 在实例化对时触发,优先与__init__

__call__: 对象调用方法
触发时机: 将对象当成函数使用的时候,会默认调用此函数中内容

__del__:  delete的缩写 析构魔术方法
触发时机:当对象没有用(没有任何变量引用)的时候被触发
import sys
print(sys.getrefcount(p))	# p对象对应的内存地址,应用的次数加1

__str__:  方法中必须有关键字return 

4 类的私有化

私有化: 如果想让类的内部属性不被外界直接访问,可以在这个属性的前面加两个下划线__ ,在Python中,如果一个属性的前面出现 __,就表示这个属性只能在当前类的方法中被直接访问,不能通过对象直接访问,这个变量就被称为私有变量
封装: 1. 私有化属性  2.定义公有set和get方法
__属性: 就是将属性私有化,访问范围仅仅限于类中

"""
好处:
1. 隐藏属性不被外界随意修改
2. 也可以修改:通过函数
   def setXXX(self,xxx):
       3. 筛选赋值的内容
         if xxx是否符合条件
             赋值
          else:
             不赋值
3.如果想获取具体的某一个属性
  使用get函数
    def getXXX(self):
       return self.__xxx
"""
class Student:
    
    def __init__(self, name, age):
        self.__name = name  # 长度必须6位
        self.__age = age
        self.__score = 59

    # 定义公有set和get方法
    # set是为了赋值
    def setAge(self, age):
        if age > 0 and age < 120:
            self.__age = age
        else:
            print('年龄不在规定的范围内')

    # get是为了取值
    def getAge(self):
        return self.__age

    # 修改名字的时候,长度必须6位
    def setName(self, name):
        if len(name) == 6:
            self.__name = name
        else:
            print('名字不是六位')

    def getName(self):
        return self.__name

    def __str__(self):
        return '姓名:{},年龄:{},考试分数:{}'.format(self.__name, self.__age, self.__score)

yupeng = Student('yupeng', 18)
print(yupeng)   # 姓名:yupeng,年龄:18,考试分数:59
yupeng.setAge(120)
print(yupeng)   # 年龄不在规定的范围内  姓名:yupeng,年龄:18,考试分数:59

5 类的私有化的propert方法

# 在开发中看到一些私有化处理: 装饰器
class Student:
    def __init__(self, name, age):
        self.name = name
        self.__age = age

    # 先有getxxx,
    @propert
    def age(self):
        return self.__age

    # 再有set,因为set依赖get
    @age.setter
    def age(self, age):		# 函数命与上面age一样
        if age > 0 and age < 100:
            self.__age = age
        else:
            print('不在规定的范围内')

    def __str__(self):
        return '姓名:{},年龄:{}'.format(self.name, self.__age)


s = Student('peng', 20)
s.name = 'xiaopeng'
print(s.name)

s.age = 130
print(s.age)

6 案例:工资管理程序

'''
编写一个简单的工资管理程序,系统可以管理以下四类人:工人(worker)、销售员(salesman)、经理(manager)、销售经理(salemanger)。
所有的员工都具有员工号,姓名,工资等属性,有设置姓名,获取姓名,获取员工号,计算工资等方法。
  1)工人:工人具有工作小时数和时薪的属性,工资计算法方法为工作小时数*时薪。
  2)销售员:具有销售额和提成比例的属性,工资计算方法为销售额*提成比例。
  3)经理:具有固定月薪的属性,工资计算方法为固定月薪。
  4)销售经理:工资计算方法为销售额*提成比例+固定月薪。
请根据以上要求设计合理的类,完成以下功能:
   1)添加所有类型的人员
   2)计算月薪
   3)显示所有人工资情况
'''
class Person:
    def __init__(self, no, name, salary):
        self.no = no
        self.name = name
        self.salary = salary
    def __str__(self):
        msg = '工号:{},姓名:{},本月工资:{}'.format(self.no, self.name, self.salary)
        return msg
    def getSalary(self):
        return self.salary

class Worker(Person):
    def __init__(self, no, name, salary, hours, per_hour):
        super().__init__(no, name, salary)
        self.hours = hours
        self.per_hour = per_hour
    def getSalary(self):
        money = self.hours * self.per_hour
        self.salary += money
        return self.salary

class Salesman(Person):
    def __init__(self, no, name, salary, salemoney, percent):
        super().__init__(no, name, salary)
        self.salemoney = salemoney
        self.percent = percent
    def getSalary(self):
        money = self.salemoney * self.percent
        self.salary += money
        return self.salary

# 创建子类对象
w = Worker('001', 'king', 2000, 160, 50)
s = w.getSalary()
print('月薪是:', s)
print(w)
print('----------------------------------------')
saler = Salesman('002', 'lucy', 5000, 50000000, 0.003)
s = saler.getSalary()
print('月薪是:', s)
print(saler)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值