Python基础学习Day_07

引言

        hello啊,兄弟们,这几天更新的都没怎么好好唠嗑,今天我学习的是面向对象的内容,学过java和c嘎嘎的同学应该都不陌生吧,当初在学习这一章节的时候简直是生不如死啊。好在那段时间都挺过来了,现在看这东西,比之前那几章节都快,昨天摸了一天🐟,今天本来说8点开始的,结果听说农药上了一个10v10的模式,我也是赶紧上号体验了一番。不打不知道啊,一打就在对面两条中路防御塔空隙里面来回蹦迪,第一次玩这样的地图实在是不适应。哎,等我打完游戏,时间就已经来到了10点,我就紧赶慢赶看完了今天的所有知识点,开始了今天笔记总结,计划明天,后天写两个小项目,就写学生管理系统和银行管理系统吧,毕竟是java开发出生,对后台系统有种莫名的亲切,计划是一个用字典和列表写,另一个用面向对象写,顺便到最后吧存储的最终数据做一个导入导出操作,这涉及到之前学IO的操作,当然我会建立一个git仓库,存放我的代码,供大家参考。话不多说,开始今天的博客之旅,现在是北京时间22:27.

一.什么是面向对象

        面向对象编程(Object-Oriented Programming,OOP)是一种常用的编程思想,它强调万物皆对象,因此在编程时我们可以将现实世界中的事物抽象成程序中的对象,从而更好实现软件的设计与开发。与传统的基于函数的编程不同,面向对象编程注重于将数据与行为封装在一起,即对象既包含数据状态,还包含可调用的行为方法。具有三大特性,封装,继承以及多态。

二.类和对象的概念定义

:类是一个抽象的概念,是模板,是一个参考物。用来描述具有相同属性和方法的集合。

比如:人类,动物类。

对象:具体存在的事物。精准存在,可以看得见摸得着的东西

类和对象的关系:从实际来看,可以表示为,对象归为类。类是最大的,对象把类给精确化了。

类的构成:

1、类的名称:类名

2、类的属性:一组数据

3、类的方法:允许对类操作的方法 类里面的函数,称之为方法

类的定义:

1、class 类名:

2、class 类名():括号里面可以什么都不写的时候。继承obj

3、class 类名(object):

三.对象的创建

        对象的创建也叫做类的调用,默认是调用类中的构造方法。每个类中都用构造方法,如果没有重写或者重载,那就是调用系统默认的无参构造方法。

class Student2():
    def __init__(self):
        self.name = "张三"
        self.age = "20"
        self.id = "123456"

    def __str__(self):
        return f"{self.name},{self.age},{self.id}"

#创建对象
stu2 = Student2()

四.私有属性

        学过java的都知道,私有属性使用prative修饰的字段,在python里面,私有属性或者私有方法都是用1(2)个下划线+字段名表示的,当然读取和修改私有属性也用get()和set()

class Book:
    def __init__(self): # 不需要调用,在特定时间、特定地点。自动触发的函数
        self.name = "西游记"
        self.id = "1001"
        self._author = "吴承恩"
        self.classify = "神话"

    def __read(self):
        print("小明爱读书")

    def info(self):
        Book.__read(self)
        print(f"名字为{self.name}")
        print(f"id为{self.id}")
        print(f"作者是{self._author}")
        print(f"属于{self.classify}的故事")
        print(f"图书名称{self.name},id号{self.id},作者{self._author},属于{self.classify}类的故事")  # 属于class内部,在内部运行,私有属性可以全部打印出来,



b = Book()
#读取不到私有属性,会报错
# print(b._author)

#读取不到私有方法,会报错
# b.read()

#私有属性和私有方法被封装在类中的方法时候,类中的方法可以访问,不报错
b.info()

# 小明爱读书
# 名字为西游记
# id为1001
# 作者是吴承恩
# 属于神话的故事
# 图书名称西游记,id号1001,作者吴承恩,属于神话类的故事

五.魔法函数

        所谓魔法函数是系统内部自己嵌套的函数,比方说构造函数如果不重新写,在创建对象的时候会使用系统默认的无参构造函数,目前常用的三个魔法函数,如下:

# __init__  触发条件,对象一旦创建,则自动执行
# __str__ 触发条件,对象打印的时候,可以将对象的地址转化为自定义的输出内容
# __lt__ 触发条件:两个对象参与比较,自动触发该魔法方法
class Number:
    def __init__(self,value):
        self.value = value
    def __lt__(self,other):
        return self.value < other.value

n1 = Number(3)
n2 = Number(4)
# print(n1 < n2) #True
print(n1.__lt__(n2))

六.类的成员

类的成员:区分为两大类:属性和方法

属性:1、实例属性[普通字段] 2、类属性[静态字段]

方法:1、实例方法[普通方法] 2、类方法[类方法]

类属性

1、字段是固定的:不会随着对象的改变而改变。

2、使用静态字段(类属性)减少内存消耗。

3、如果传递的参数要随着对象的变化而变化,那么要用实例属性。

class A:
    name = "狗岁"   #name就是静态字段,即类属性
    pass

静态方法

方法被@staticmethod 修饰

self 不再呆滞对象本身,只是一个简单的参数

可以不实例化对象,直接进行调用。通过类名.方法名()、

Class A:
    @staticmethod
    def run():
        print("A在奔跑")

#直接用A类去调用方法
A.run()    #A在奔跑

类方法

方法被@classmethod修饰

也不需要传递self,系统自带的关键字(cls)指代类本身。

使用和静态方法一样,直接用类名.方法名

Class A:
    @classmethod
    def run():
        print("A在奔跑")

#直接用A类去调用方法
A.run()    #A在奔跑

修饰器

这个是我刚学的东西,我在写这篇帖子之前还不知道这是啥玩意,看完以后才懂,有点类似代理的意思。这个是老师给我的文档介绍,待会我用代码给你们解释一下。

装饰器:(函数)
1、装饰器函数,必须接收一个函数来作为参数。并且返回一个新的函数。
2、装饰器函数,一般都是在函数内部定义一个新的函数,用来包裹旧的函数。在原始的函数之前来调用增加或者删除其他功能。
3、装饰器函数,@ 将其作用到其他函数
@: 称之为语法糖。
装饰器遵循的原则封闭开放原则。

首先,如果我写一个函数

class f():
    time.sleep(1000)
    print("我想月入过万")

我想测试这个函数的编译时间

def F():
    start = time.time()
    time.sleep()
    end  = time.time()
    print(end - start)

一个这样的函数还好,但是有很多这样对f()呢,这时候就需要修饰器出场

def F(fun())
    start = time.time()
    f()
    end = time.time()
    print(end - start)

def f1():
    time.sleep()
    print("我想月入过万")


def f2():
    time.sleep()
    print("我也想")

F(f1())
F(f2())

当然也可以使用@语法糖

def F(fun())
    start = time.time()
    f()
    end = time.time()
    print(end - start)
@F         #默认调用F(fun())函数
def f1():
    time.sleep()
    print("我想月入过万")

@F
def f2():
    time.sleep()
    print("我也想")

受保护的方法

类似静态方法和类方法,在方法头上加@property注解的方法,其他类不读取修改,只能通过get()方法进行读取,只读不能通过其他方法修改。

class Demo:
    def __init__(self):
        self.name = "rose"

    @property
    def get_name(self):
        print(self.name)

d = Demo()
d.get_name

七.封装,继承,多态

        终于来到面向对象最重要的部分了,因为之前学过,感觉理解起来不麻烦,所以直接就一块写了。

封装

面向对象的基本特征之一,[封装对象内部的细节,只保留对外的接口]

要调用你封装的细节,符合你对象内部的特征

以下是一个梨子,应为id是私有属性,外部类无法访问,所有封装了get_id()和set_id()来对私有变量进行读取和修改,私有方法外部类无法访问,也是同理。

class Student():
    def __init__(self, name):
        self.__id = ""
        self.name = name

    def set_id(self, id):
        if id >= 0:
            self.__id = id
        else:
            self.__id = 0

    def get_id(self):
        return self.__id


stu1 = Student("小张")
stu1.set_id(-10)
print(stu1.get_id())

继承

继承:

面向对象的特征之一:     子类继承父类(亲爹)

重写:    当子类的方法和父类一样的时候。优先执行子类。

单继承

# 单继承
class Animal(ABC):
    def __init__(self,name,age):
        self.name = name
        self.age = age
  
    def drink(self):
        print(f"{self.name}:在喝水")

class Dog(Animal):

    # 没有构造方法
    def eat(self):
        print(f"{self.name}在吃东西")
    def play(self):
        print("在玩骨头")

d = Dog("旺财","12")
d.drink()
d.play()

多继承

深度优先,从左到右

class Horse():
    def __str__(self, name):
        self.name = name

    def show_info(self):
        print(f"马叫{self.name}")

    def run(self):
        print("马在跑")

class Donkey():
    def __str__(self, name):
        self.name = name

    def show_info(self):
        print(f"驴叫{self.name}")

    def run(self):
        print("驴跑的慢")

    def roll(self):
        print("驴打滚")


class MM(Horse, Donkey):
    def __init__(self, name, age):
        self.name = name
        self.age = age


m1 = MM("小罗", 2)
m1.roll()
m1.run()        #因为先继承的Horse,所以输出结果为  马在跑

抽象基类继承

子类继承抽象基类,必须实现抽象基类中抽象方法,并且抽象基类无法实现自己实现实力,只能通过多条来实现实例化。抽象方法头上有个注解是@abstractmethod

class Animal(ABC):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    @abstractmethod
    def drink(self):
        print(f"{self.name}:在喝水")

class Dog(Animal):
    def drink(self,name):
        print(f"{name}不爱喝水")
    # 没有构造方法
    def eat(self):
        print(f"{self.name}在吃东西")
    def play(self):
        print("在玩骨头")
d = Dog("旺财","12")
d.drink("wo")

子类使用父类方法时可以使用super()函数

Class A:
    @abstractmethod
    def drink(self):
        print("我要喝水")

Class B(A):
    def drink(self):
        super.drink(self)
        print("我不喝水")

多态

必须要有继承才会有多态

继承又重写父类

class Student():
    def speak(self):
        print("同学们,大家喊123")


class Stu1(Student):
    def speak(self):
        print("小张会讲话,会说ABC")


class Stu2(Student):
    def speak(self):
        print("小李会说话,会说欧耶")


class Stu3(Student):
    pass

s1 = Stu1()
s2 = Stu2()
s3 = Stu3()
s1.speak()
s2.speak()
s3.speak()

在这里我就在考虑,java中有向上转型和向下转型,向上转型无所谓,但是向下转型会先判断类型是否相同,比方说,猫向上转型成动物,这个动物能向下转型成狗吗?显然是不可能的,所以在python里有没有相同的定义呢,我找了一下,显然是没有的,python的多态主要还是显示在,同一类的对象调用共同的行为或者说是方法,这里叫做鸭子模型。 Python解释其中,不坚持发生多态的对象是否继承一个父类,但是,只有有相同的行为。

class Animal():
    def speak(self):
        print("动物在叫,不知道怎么教的")


class Dog:
    def speak(self):
        print("狗在叫")


class Cat:
    def speak(self):
        print("猫在叫")


class Car:
    def speak(self):
        print("汽车在叫")


def start(obj):
    obj.speak()


d = Dog()
start(Dog())
start(Cat())
start(Car())

结语

OK了,面向对象,到这里就结束了,注意核心,封装继承多态。现在是北京时间23:42,明天工作的地方要开始直播了,我得早点睡了,今天任然是python小白,梦想是月入过万,mai起!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值