Python基础之面向对象初识

Python基础之面向对象初识

面向对象(Object Oriented,OO)是计算机编程技术发展到一定阶段的产物,如今已在包括软件开发和程序设计在内的多个领域占据主导地位。
##1. 什么是面向对象
什么是面向对象?说起这个问题,就不得不引出一个经典的问题:

问:把大象装进冰箱需要几步?

不管有没有编程基础的人都会回答:

三步。
1.打开冰箱
2.把大象放进冰箱
3.关上冰箱

而这种思维方式,看似是一个笑话,但却是标准的面向过程(Procedure Oriented)的思想。它以事件为中心,把整个部分分成若干个步骤,之后按照步骤一步一步执行,这便是面向过程。

而面向对象呢?只需要分两步即可

1.创造一个可以拥有将大象装进去功能的冰箱
2.让冰箱将大象装进去

这种思维便是面向对象(OO)。面向对象以事物为中心,首先考虑完成本件事情需要哪些事物参与,然后考虑每一个事物具有的行为和特征,最后由这些事物的具体实例通过执行自身的功能完成本次事件

##2.类与对象

面向对象的核心是类和对象

何为类?何为对象?

如果引用百度百科上的解释

类和对象(class)是两种以计算机为载体的计算机语言的合称。对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型。它们的关系是,对象是类的实例,类是对象的模板。

只会让你更晕

简单来说,类是一种抽象,自然界不存在该个体;而对象是类的具象化,是指自然界某个特定的物体。

是否还晕?

再简而言之,当你想一个东西,如果每个人想的都不一样,那便是。如在脑海中想象一个苹果,有人想的红的,有人想的青的,各种各样,这便是类。
而当你想某个特定的事物,所有人想的都是同一个,那便是对。还如在脑海中想象一个苹果,不过这个苹果指定为你手中正在吃的那个苹果,周围人看到了脑海中都会出现一样的事物,这便是对象。

注意面向对象中真正执行操作的是对象

##3.类与对象的创建
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的

类的定义语法为

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>
class Dog:
    def bite(self):
        print("咬死你")

dog = Dog()
dog.bite()

以上为一个简单的类

但如果我们需要给狗类赋予特定的属性呢?如什么品种?颜色?等等

这就要用到__init__内置函数了

class Dog:
    def __init__(self, kind, weight, height, color, name):
        self.kind = kind
        self.weight = weight
        self.height = height
        self.color = color
        self.name = name
    def bite(self):
        print("咬死你")

dog = Dog("二哈", 100, 100, "黑白", "二愣子")
dog.bite()

__init__(self):初始化方法,Python内置方法,在类中定义,当通过类创建具体实例时,该方法自动调用
self:指代类中所创建的具体实例对象

但问题又来了
如果用户随意修改对象信息,甚至设置不合理信息该如何限制?
如下:

class Dog:
    def __init__(self, kind, weight, height, color, name):
        self.kind = kind
        self.weight = weight
        self.height = height
        self.color = color
        self.name = name
    def bite(self):
        print("咬死你")
    def say(self):
        print("我有%dkg重" % self.weight)

dog = Dog("二哈", 100, 100, "黑白", "二愣子")
dog.weight = -1
dog.say()
dog.bite()
# 我有-1kg重
# 咬死你

有过编程经历的小伙伴一定会说可以用public、private、protected等权限关键字限制呀
很对
可惜Python并不支持╮(╯﹏╰)╭

在Python中,私有方法可以使用__变量名__方法名双下划线+变量名/方法名)来控制,等价于private,表明私有内容,此时该属性/方法的访问权限只能在当前类中访问。而普通类型则是默认为公开内容,等价于public
因此可以如此写

class Dog:
    def __init__(self, kind, weight, height, color, name):
        self.__kind = kind
        self.__weight = weight
        self.__height = height
        self.__color = color
        self.__name = name
    def bite(self):
        print("咬死你")
    def say(self):
        print("我有%dkg重" % self.__weight)

dog = Dog("二哈", 100, 100, "黑白", "二愣子")
dog.weight = -1 # 无法改变
dog.say()
dog.bite()
# 我有100kg重
# 咬死你

说是无法修改访问了,其实还是可以使用dog._Dog__weight = -1修改访问的,然而这并没有什么用纯粹找事,所以并不建议使用

那如果需要修改某个特定值,如二哈长胖了,该如何是好?

在C#等语言中存在着get();set();方法可以使私有变量被访问,并且可以筛选修改的内容。
在Python中则不同,你可以有两种选择:
一、使用自定义方法

class Dog:
    def __init__(self, kind, weight, height, color, name):
        self.__kind = kind
        self.__weight = weight
        self.__height = height
        self.__color = color
        self.__name = name
    # 自定义get
    def getWeight(self):
        return self.__weight
    # 自定义set
    def setWeight(self, weight):
        if isinstance(weight, int) and weight > 0:
            self.__weight = weight
        else:
            raise ValueError("Value Error!")
    def bite(self):
        print("咬死你")
    def say(self):
        print("我有%dkg重" % self.__weight)

dog = Dog("二哈", 100, 100, "黑白", "二愣子")
dog.setWeight(120) # 使用自定义方法修改体重
dog.say()
dog.bite()
# 我有120kg重
# 咬死你

二、使用系统内置装饰器@property

class Dog:
    def __init__(self, kind, weight, height, color, name):
        self.__kind = kind
        self.__weight = weight
        self.__height = height
        self.__color = color
        self.__name = name

    @property
    def kind(self):
        return self.__kind

    @kind.setter
    def kind(self, kind):
        if isinstance(kind, str):
            self.__kind = kind
        else:
            raise ValueError("Value Error")

    @property
    def weight(self):
        return self.__weight

    @weight.setter
    def weight(self, weight):
        if isinstance(weight, int) and weight > 0:
            self.__weight = weight
        else:
            raise ValueError("Value Error")

    @property
    def height(self):
        return self.__height

    @height.setter
    def height(self, height):
        if isinstance(height, int) and height > 0:
            self.__height = height
        else:
            raise ValueError("Value Error")

    @property
    def color(self):
        return self.__color

    @color.setter
    def color(self, color):
        if isinstance(color, str):
            self.__color = color
        else:
            raise ValueError("Value Error")

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

    @name.setter
    def name(self, name):
        if isinstance(name, str):
            self.__name = name
        else:
            raise ValueError("Value Error")

    def bite(self):
        print("咬死你")
    def say(self):
        print("我有%dkg重" % self.__weight)

dog = Dog("二哈", 100, 100, "黑白", "二愣子")
dog.weight = 120 # 直接使用属性名修改
dog.say()
dog.bite()
# 我有120kg重
# 咬死你

setter和getter方法的作用:可以灵活的设置对象私有属性的访问权限,避免用户随意修改属性中的数据,可以有效保护数据的安全
@property:直接修饰对应属性的getter方法,被修饰的方法名字和对应属性名一致,此时装饰器@property会自动生成跟该getter方法一致的setter方法,该装饰器直接修饰与属性名一致的setter方法

在此推荐使用第二种方法

紧接着又发现了问题(我就是十万个为什么 ̄▽ ̄),如果我再实例化一个阿拉斯加的对象,和上一个对象一样,他们都会叫,都会咬人。如果一个一个定义太过麻烦,如果我要定义200只狗是否需要重复占用200个相同内容的空间?这对系统内存合理分配很不友好。

所以类方法类属性就及时出现了

类属性:直接在类中定义的属性称为类属性,比如dogSay,类属性的所有权归当前类所有,对象只能够获取该属性的值但不能修改该属性值
类方法:通过@classmethod修饰的方法属于类方法,该方法的所有权属于当前类,对象只能调用,不能修改
注意:类属性和类方法对应的计算机内存空间只有一个,所有的属性访问操作时操作的是同一块空间。这样做可以有效的帮我们减少计算机内存开销

class Dog:
    dogSay = "汪"
    @classmethod
    def bite(self):
        print("咬死你")
    def __init__(self, kind, weight, height, color, name):
        self.__kind = kind
        self.__weight = weight
        self.__height = height
        self.__color = color
        self.__name = name

    @property
    def kind(self):
        return self.__kind

    @kind.setter
    def kind(self, kind):
        if isinstance(kind, str):
            self.__kind = kind
        else:
            raise ValueError("Value Error")

    @property
    def weight(self):
        return self.__weight

    @weight.setter
    def weight(self, weight):
        if isinstance(weight, int) and weight > 0:
            self.__weight = weight
        else:
            raise ValueError("Value Error")

    @property
    def height(self):
        return self.__height

    @height.setter
    def height(self, height):
        if isinstance(height, int) and height > 0:
            self.__height = height
        else:
            raise ValueError("Value Error")

    @property
    def color(self):
        return self.__color

    @color.setter
    def color(self, color):
        if isinstance(color, str):
            self.__color = color
        else:
            raise ValueError("Value Error")

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

    @name.setter
    def name(self, name):
        if isinstance(name, str):
            self.__name = name
        else:
            raise ValueError("Value Error")
    def say(self):
        print("我有%dkg重" % self.__weight)

dog1 = Dog("二哈", 100, 100, "黑白", "二愣子")
dog2 = Dog("阿拉斯加", 100, 100, "黑白", "二狗子")
dog1.bite()
# 咬死你
dog2.bite()
# 咬死你
print(dog1.dogSay)
# 汪
print(dog2.dogSay)
# 汪
# 如果改变dog1的dogSay会发生什么?
dog1.dogSay = "喵"
print(dog1.dogSay)
# 喵
print(dog2.dogSay)
# 汪
# 类属性的所有权归当前类所有,对象只能够获取该属性的值但不能修改该属性值

自此我们就创建了一个最基本的类,并实例化对象调用╰(:з╰∠)_

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值