Python3-面向对象

面向对象

  1. 对象创建、属性、定义
  2. 封装
  3. 继承
  4. 多态
  5. 单例

走进对象的世界

类的基本操作

定义

"""
面向对象:
程序      现实中
对象      具体的事物

现实中的事物  转换成代码程序
万事万物皆对象
    面向过程    会因为局部影响全局,几乎全部影响
优点:
    复用,更加灵活(只需要修复出现问题的结点)
    关注的 个体 + 关系
    类 、对象 、 属性、方法

对象:手机
对象的集合:
    共同的特征:颜色 品牌 大小  价格      动作:打电话 发短信 上网 打游戏
类别:
    手机类     学生类
    特征: 姓名  年龄 身高  特征  血型  婚否 ------------> 属性
    动作:刷抖音 敲代码  看书...------------> 方法
    多个对象-------->提取对象的共同特征和动作--------->封装到一个类
"""
"""
# 定义 首字母大写,驼峰命名法;默认继承Object
class

"""

class Phone:
    pass
    # 属性
    brand = '苹果'
    # 方法


# <class '__main__.Phone'>
print(Phone)

# 使用模型创建对象
yh = Phone()  # <__main__.Phone object at 0x000001DEAED95A88>
print(yh)
print(yh.brand)
yh.brand = '华为'
print(yh.brand)

ff = Phone()
print(ff)  # <__main__.Phone object at 0x000001DEAED95AC8>
print(yh.brand)
ff.brand = '小米'
print(ff.brand)

print("属性".center(20, '*'))
"""
对象:
    对象名= 类名(): 在内存就是内存空间分配
属性:
    类属性和对象属性
        先找对象属性再找类属性;
        如果再找到对象属性则不会再找类属性

"""
class Student:
    pass
    # 类属性
    name = ''
    age = 0


xiaowei = Student()

# 对象属性
xiaowei.name = '小伟'  # 赋值操作
xiaowei.age = 18

print(xiaowei.name)
print(xiaowei.age)

# 再创建一个对象
yy = Student()
yy.age = 30
print(yy.name)
print(yy.age)

# 初始化类属性

Student.age = 18
Student.name = "中国"

print(yy.name)

属性

  • 属性获取定义
"""
私有化装饰器:
    先get后set:
        @property
        @age.setter
"""


class Student:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
        self.__score = 50

    def __str__(self):
        return "姓名是:" + self.__name + ",年龄:" + str(self.__age) + ",分数:" + str(self.__score)

    # 先定义get_age
    @property
    def age(self):
        return self.__age

    # 再定义set_age;依赖于get
    @age.setter
    def age(self, age):
        if age < 0 or age > 120:
            print("年龄没有在合理范围内")
        else:
            self.__age = age

    """
    # 定义公有的get和set方法
    def set_age(self, age):
        if age < 0 or age > 120:
            print("年龄没有在合理范围内")
        else:
            self.__age = age

    def get_age(self):
        return self.__age

    def set_score(self, score):
        self.__score = score

    def set_name(self, name):
        if len(name) > 6:
            print("名字长度不能超过六位")
        else:
            self.__name = name

    def get_name(self):
        return self.__name
    """


s = Student("lily", 30)

s.age = 131
result = s.age  # 因为加了装饰器,可以像使用name一样

print(result)

print(dir(s))

方法

  • 方法分类
"""
类中方法:
    种类:普通方法、类方法、静态方法、魔术方法

    类方法:(@classmethod)
        特点:
            1. 定义需要依赖装饰器@classmethod
            2. 类方法中参数不是一个对象,而是类
            3. 类方法只可以使用类属性,无法访问对象属性
            4. 类方法不依赖对象
            5.不能使用普通方法
        作用:
            因为只能访问类属性和类方法,所以可以在对象创建之前,如果需要完成一些动作(功能),就可以方法类方法
    静态方法:(@staticmethod)
        类似于类方法
        1. 需要装饰器staticmethod
        2. 类中的静态方法无需传递参数(cls、self)
        3. 也只能访问类的属性和方法,对象的无法访问
        4. 加载时机同类方法
    总结:
        类方法 静态放啊
            1、装饰器不同
            2、类方法有参数、静态方法无参数
            3、都可以通过类名i盗用
            4、都可以再创建对象之前使用,因为是不依赖于对象。
        普通方法  与类方法和静态的区别
            1、没有装饰器
            2、永远依赖对象
            3、普通方法依赖对象,每个方法都有self
            4、只有创建对象才可以调用、否则无法调用

"""

print("普通方法".center(30, "*"))

class Person:
    birthday = "1992-11-01"
    __dur_time = 100  # 前面加__ 私有

    def __init__(self, name, age):
        """
        定义共性特征:就是构造函数
        :param name: 姓名
        :param age: 年龄
        """
        self.name = name
        self.age = age

    def eat(self, food):
        print("{}正在吃{}!".format(self.name, food))
        print("{}几岁了".format(self.age))

    def run(self):
        print("{}今年{}岁了,正在跑步!".format(self.name, self.age))

    def info(self):
        print("{}出生于{}".format(self.name, self.birthday))  # 建议使用self.birthday,而不是Person.birthday

    @classmethod
    def update_dur_time(cls):
        """
        修改成员变量
        :return:
        """
        cls.__dur_time = 101

    def get_update_dur_time(self):
        return self.__dur_time
p = Person("张三", 18)
p.eat("红烧肉")
p.run()

p.name = '李四'
p.age = 28
p.eat("狮子头")

p.name = "Lucy"
p.info()
p.name = "Tony"
p.birthday = "1979-10-01"
p.info()

Person.update_dur_time()
result = p.get_update_dur_time()
print("消耗的时间{}".format(result))

print("类方法".center(30, "*"))


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

    def run(self):
        print("{}在院子中跑来跑去".format(self.nickname))

    def eat(self):
        print("吃饭。。。。。。。。。。。。")
        self.run()

    @classmethod
    def test(cls):  # cls class
        print(cls)  # <class '__main__.Dog'>
        # print(cls.nickname)  #报错
        # print(self.nickname)  #报错
        print()
        # cls.run() #报错


d = Dog("小黄")
d.run()

Dog.test()  # L

print("静态方法".center(30, "*"))


class People:

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

    @classmethod
    def update_name(cls):
        cls.__name__ = "葫芦娃"

    @staticmethod
    def show():
        print("静态方法")
        print("name =", People.__name__, sep=" ")


People.update_name()
People.show()

  • 魔术方法
# __str__
"""
    魔术方法:内置的函数,默认直接调用,如果需要改变返回值,需要重写
        __str__ :

    总结魔术方法:
        __init__ __str__

        了解
        __new__ 开辟空间,
        __del__ 没有指针调用的时候会调用  :一般不需要重写

"""


class Person:

    # 不重写默认是None
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # 魔术方法:重写了 :<__main__.Person object at 0x0000022DE5135B88>
    def __str__(self):
        print(self.name)
        return "姓名:" + self.name + "年龄:" + str(self.age)


p = Person("张三", 18)
result = p.__str__()
print(result)

  • 类方法
# 类方法

class Phone:
    brand = '小米'
    price = 2988
    type = '米8'

    # 魔术方法 :前后都有2个__名字__ (系统默认执行)
    def __init__(self):
        """
        初始化
        """
        print("init....")
        self.address_book = [] # 动态添加属性

    def call(self):  # self 是不断发生改变的
        """
        self 就是对象
        :return:
        """
        print("self----------->", self)
        print("正在打电话。。。。。。。")
        print("正在访问通讯录。。。。。。。")
        for person in self.address_book:  # 不能保证每个self种保证address_book;所以有阴影
            print(person.items())


xm = Phone()
print(xm.brand, xm.type, xm.price, sep=" ")
xm.address_book = [{"18799191912": "张三"}, {"18799191913": "李四"}]
print(xm)
print(xm.call())

hw = Phone()
hw.brand = '华为'
hw.type = 'mete 8'
hw.price = 3999
print(hw.brand, hw.type, hw.price, sep=" ")
print(hw)
print(hw.call())
print("*" * 30)

# 验证self

xm.note = '备注1:小米'
hw.note = '备注2:华为'

print(xm.note)
print(hw.note)

三性:封装、继承、多态

封装

"""
# 私有化:
    __属性: 只能在类中赋值和修改, 访问权限进限制于类里边
    好处:
        隐藏属性,不被随意修改
        可以通过提供的set_属性名()函数进行修改(对外的通用接口)
            可以通过set_属性名()进行限制判断
    # attribute:
        get_age', 'get_name', 'set_age', 'set_name', 'set_score
        '_Student__age', '_Student__name', '_Student__score'
封装:
    私有化属性、定义公有的set get方法;
继承:

多态:
"""


class Student:
    # __age = 19  # 类属性
    # __score = 59

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

    def __str__(self):
        return "姓名是:" + self.__name + ",年龄:" + str(self.__age) + ",分数:" + str(self.__score)

    # 定义公有的get和set方法
    def set_age(self, age):
        if age < 0 or age > 120:
            print("年龄没有在合理范围内")
        else:
            self.__age = age

    def get_age(self):
        return self.__age

    def set_score(self, score):
        self.__score = score

    def set_name(self, name):
        if len(name) > 6:
            print("名字长度不能超过六位")
        else:
            self.__name = name

    def get_name(self):
        return self.__name


s = Student("张三", 18)
print(s)
s.set_age(28)
print(s)
s1 = Student("李四", 20)

s1.set_age(128)
print(s1)

s1.set_name("tomorrow")
print(s1)
s1.set_name("lucy")
print(s1)
print(s1.get_name())
print(s1._Student__name)  # 底层做了伪封装,不建议这么使用,建议通过set和get访问;_Student__name系统将私有化的属性修改的名称

print(dir(Student))

print(dir(s1))

继承

  • has a 、is a
"""
has a:
    在一个类中引用另一个自定义的类 :类如在student中使用computer
is a:(实类的判断) base class 父类 基类
    系统类型
        str int  float
        list dict tuple set
    自定义类型:
        s = Student()       s 是student类型的对象


继承:
    1、高内聚、降低重复代码
    2、
特点:
    1、如果类中不定义__init__,调用父类中 supper class 的__init__
    2、如果类继承父类也需要定义自己的__init__,就需要在当前类__init__调用父类的__init__
    3、如何调用父类__init__:
        super().__init__(参数)
        super(类名,对象).__init__(参数)
    4、如果父类有eat(),子类也定义了一个eat方法,默认搜索的原则;先找当前类,再找父类:
        t.eat()
        override:重写(覆盖)
            父类提供的方法无法满足子类的需求,需要子类定义一个同名的方法
    5、
"""


class Computer:
    def __init__(self, brand, type, color):
        self.brand = brand
        self.type = type
        self.color = color

    def on_line(self):
        print("正在使用电脑上网")

    def __str__(self):
        return self.brand + "---" + self.type + "---" + self.color


class Book:
    def __init__(self, book_name, author, number):
        self.book_name = book_name
        self.author = author
        self.number = number

    def __str__(self):
        return self.book_name + "---" + self.author + "---" + str(self.number)


class Student:  # has a
    def __init__(self, name, computer, book):
        self.name = name
        self.computer = computer
        self.books = []
        self.books.append(book)

    def borrow_book(self, book):
        for bk in self.books:
            if bk.book_name == book.book_name:
                print("已经借过了")
            else:
                self.books.append(book)
                print("添加成功了")

    def show_book(self):
        for book in self.books:
            print(book.book_name)

    def __str__(self):
        return self.name + "---" + str(self.computer) + "---" + str(self.books)


computer = Computer("联想", "e430", "银色")

b = Book("盗墓笔记", "南派三叔", 10)

s = Student("张三", computer, b)

print(s)
bk = Book("鬼吹灯", "天下霸唱", 8)

s.borrow_book(bk)

print("-------------------------->")
s.show_book()

print("is a".center(30, "*"))


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

    def eat(self):
        print(self.name + "正在吃饭......")

    def run(self):
        print(self.name + "正在跑步......")


class Employee(Person):
    def __init__(self, name, age, salary):
        super(Employee, self).__init__(name, age)
        self.salary = salary

    pass


class Teacher(Person):
    def __init__(self, name, age, clazz):
        """
         调用父类的init初始化
        :param name: 姓名
        :param age: 年龄
        :param clazz: 班级
        """
        super().__init__(name, age)
        self.clazz = clazz

    def attend_class(self):
        print("{}老师正在上课,马上下课".format(self.name))

    def eat(self):
        """
        注意:
            按照名称寻找,而不是像java一样根据参数判断
        :return:
        """
        print("子类正在重构父类的eat方法")

    def __str__(self):
        return "{}老师,今年{}岁,现在教{}班".format(self.name, self.age, self.clazz)

    pass


e = Employee("张三", 18, 10000)

e.run()
e.eat()

t = Teacher("李四", 30, 5)
print(t)
t.attend_class()
t.eat()

  • 单继承
# 继承 is a ;has a
"""
公路(road)
    属性 公路名称 公路长度

    车(car)
        属性 车名 时速
        方法:
            1,求车名在那条公路上以多少时速行驶多长时间;
                get_time(self,road)
            2. 初始化车属性信息  init 方法
            3. 打印对象显示车的属性信息
"""
import random


class Road:
    def __init__(self, name, length):
        self.__name = name
        self.__length = length

    @property
    def length(self):
        return self.__length

    @property
    def name(self):
        return self.__name


class Car:
    def __init__(self, brand, speed):
        self.__brand = brand
        self.__speed = speed

    def get_time(self, road):
        # ran_time = random.randint(1, 10)
        ran_time = road.length/self.__speed
        return "{}车,{},时速{},行驶{}小时".format(self.__brand, road.name, self.__speed, ran_time)

    def __str__(self):
        return "{},时速{}".format(self.__brand, self.__speed)


r = Road("丈八六路", 1200)

c = Car("大奔", 120)
result = c.get_time(r)  # 传递对象
print(result)
print(c.__str__())
  • 多继承
# 多继承
"""
允许多继承
    1、广度优先原则:如果父类中有相同名称的方法,搜索顺序
        python2 上面有区别
            经典类: 从左至右,深度优先
            新式类: 广度优先
        python3上没有区别:就是广度优先
"""
import inspect


class A:
    def test(self, a):
        print("AA", a)


class B:
    def test(self, b):
        print("BB", b)


class C(A, B):  # 解析顺序,就近原则
    def test(self, c):
        print("CC:", c)


print(inspect.getmro(C))  # 获取解析顺序
print(C.__mro__)

c = C()
c.test("c")

多态

# 多态
class Person:
    def __init__(self, name):
        self.__name = name

    def feed_pet(self, pet):
        # 判断pet是不是Pet得对象,或者pet是不是Pet子类的对象
        if isinstance(pet, Pet):

            print("{}喜欢喂养宠物{},{}".format(self.__name, pet.role, pet))
        else:
            print("不是宠物严禁饲养!")

    pass


class Pet:
    role = 'Pet'

    def __init__(self, nickname, age):
        self.__nickname = nickname
        self.__age = age

    def show(self):
        print("昵称:{},年龄{}".format(self.__nickname, self.__age))

    def __str__(self):
        return "昵称:{},年龄{}".format(self.__nickname, self.__age)


class Cat(Pet):
    role = '猫'

    def catch_mouse(self):
        print("抓老鼠")


class Dog(Pet):
    role = '狗'

    def watch_house(self):
        print("看家护院")


class Tiger:
    def eat(self):
        print("太可怕了,可以吃人")


c = Cat("小花", 3)
d = Dog("小黄", 4)
p = Person("张三")
p.feed_pet(c)
p.feed_pet(d)

t = Tiger()
p.feed_pet(t)

单例

# 开发模式
"""
开发模式:
    单例模式: 对内存的优化
"""


class Student:
    pass


class Singleton:
    # 私有化类属性,单例的地址存在这个属性
    __instance = None
    name = 'Java'

    # 重写父类:
    def __new__(cls, *args, **kwargs):
        print("--new--")
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
        return cls.__instance  # 扔给底层的__init__

    def show(self, n):
        print("--------->", Singleton.name, n)


s1 = Student()
print(s1)  # <__main__.Student object at 0x0000018FAD915FC8>
s2 = Student()
print(s2)  # <__main__.Student object at 0x0000018FAD915F48>

st1 = Singleton()
print(st1)  # <__main__.Singleton object at 0x0000023FAB56F0C8>
st1.show(5)

st2 = Singleton()
print(st2)  # <__main__.Singleton object at 0x0000023FAB56F0C8>
st2.show(7)

print(dir(Singleton))

练习


class Person:

    def __init__(self, card, name, salary):
        """

        :param card: id
        :param name: 姓名
        :param salary:薪水
        """
        self.__card = card
        self.__name = name
        self.__salary = salary

    # 注意先get、再set
    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

    def get_card(self):
        return self.__card

    def salary(self):
        return self.__salary

    def __str__(self):
        return "工号:{},姓名:{},薪资:{}".format(self.__card, self.__name, self.__salary)


class Worker(Person):
    def __init__(self, card, name, hour, hour_salary):
        super(Worker, self).__init__(card, name, hour * hour_salary)
        """

        :param hour: 工作小时
        :param hour_salary: 时薪
        """
        self.__hour = hour
        self.__hour_salary = hour_salary


class SelaMan(Person):
    def __init__(self, card, name, sales, commission):
        super(SelaMan, self).__init__(card, name, sales * commission)
        """

        :param sales: 销售额
        :param commission: 提成比例
        """
        self.__sales = sales
        self.__commission = commission
        self.__salary = sales * commission

    def salary(self):
        return self.__salary


class Manager(Person):
    def __init__(self, card, name, month_salary):
        """

        :param card:  身份id
        :param name: 姓名
        :param month_salary: 月薪
        """
        self.month_salary = month_salary
        super().__init__(card, name, month_salary)

    def salary(self):
        return self.month_salary


class SaleManager(SelaMan):
    def __init__(self, card, name, sales, commission, month_salary):
        self.__month_salary = month_salary
        self.__sales = sales
        self.commission = commission
        super().__init__(card, name, sales, commission)

    def salary(self):
        return self.__month_salary + self.__sales * self.commission


w = Worker(1, "张三", 168, 50)
print("工人工资:", w.salary())
print(w)

s = SelaMan(2, "李四", 500000, 0.1)
print("销售人员工资:", s.salary())
print(s)

m = Manager(3, "王五", 20000)
print("管理人员工资:", m.salary())
print(m)

sm = SaleManager(4, "赵六", 50000, 0.1, 25000)
print("销售主管工资:", sm.salary())
print(sm)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值