Python面向对象编程

类也是一个对象!
类就是一个用来创建对象的对象!
type类型的对象,定义类实际上就是定义了一个type类型的对象

嗯,神奇Python里是万物皆对象,玄学就完事了。。。

下图是对象创建的流程

在类的代码块中,我们可以定义变量和函数。在类中我们所定义的变量,将会成为所有的实例的公共属性,所有实例都可以访问这些变量。


注:为什么类的方法第一个形参是self(当然也可以是别的名字),这是为了指定是哪个类调用的,比如下方代码中self.name也可是换成p1.name,但是这样不具有通用性,因为每次调用的都是p1的属性值。方法每次被调用时,解析器都会自动传递第一个实参,第一个参数,就是调用方法的对象本身。

class Person :

    name = 'swk' # 公共属性,所有实例都可以访问
    
    def say_hello(self) :
        # 方法每次被调用时,解析器都会自动传递第一个实参
        # 第一个参数,就是调用方法的对象本身,
        #   如果是p1调的,则第一个参数就是p1对象
        #   如果是p2调的,则第一个参数就是p2对象
        # 一般我们都会将这个参数命名为self

        #   在方法中不能直接访问类中的属性
        print('你好!我是 %s' %self.name)

# 创建Person的实例
p1 = Person()
p2 = Person()

print(p2.name)

# 修改p1的name属性
p1.name = '猪八戒'
p2.name = '沙和尚'

p1.say_hello() # '你好!我是 猪八戒'
p2.say_hello() # '你好!我是 沙和尚'

__init__()方法

创建对象的流程:
    p1 = Person()的运行流程
      1.创建一个变量
      2.在内存中创建一个新对象
      3.__init__(self)方法执行
      4.将对象的id赋值给变量

    init会在对象创建以后离开执行
    init可以用来向新创建的对象中初始化属性
    调用类创建对象时,类后边的所有参数都会依次传递到init()中

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

    def say_hello(self):
        print('大家好,我是%s'%self.name)
p1 = Person('孙悟空')
p2 = Person('猪八戒')
p3 = Person('沙和尚')
p4 = Person('唐僧')

对象属性或方法的隐藏(伪隐藏)

可以为对象的属性使用双下划线开头,__xxx

其实隐藏属性只不过是Python自动为属性改了一个名字
实际上是将名字修改为了,_类名__属性名 比如 __name -> _Person__name

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

    def get_name(self):
        return self.__name

    def set_name(self , name):
        self.__name = name        

p = Person('孙悟空')

print(p.__name) __开头的属性是隐藏属性,无法通过对象访问
p.__name = '猪八戒'

print(p._Person__name)   
p._Person__name = '猪八戒'

print(p.get_name())

使用__开头的属性,实际上依然可以在外部访问,所以这种方式我们一般不用,一般我们会将一些私有属性(不希望被外部访问的属性)以_开头,我就认为使用_开头的属性都是私有属性,没有特殊需要不要修改私有属性。当然也可以直接修改。。。

 property装饰器:

用来将一个get方法,转换为对象的属性
添加为property装饰器以后,我们就可以像调用属性一样使用get方法
使用property装饰的方法,必须和属性名是一样的

setter方法的装饰器:@属性名.setter

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

    
    @property    
    def name(self):
        print('get方法执行了~~~')
        return self._name

    
    @name.setter    
    def name(self , name):
        print('setter方法调用了')
        self._name = name        

    @property
    def age(self):
        return self._age

    @age.setter    
    def age(self , age):
        self._age = age   

        

p = Person('猪八戒',18)

p.name = '孙悟空'
p.age = 28

print(p.name,p.age)

super()

  def __init__(self,name,age):
        # 希望可以直接调用父类的__init__来初始化父类中定义的属性
        # super() 可以用来获取当前类的父类,
        #   并且通过super()返回对象调用父类方法时,不需要传递self
        super().__init__(name)
        self._age = age

面向对象的三大特征:
  封装
      - 确保对象中的数据安全
  继承
      - 保证了对象的可扩展性
  多态
      - 保证了程序的灵活性

上边两个和Java差不多,下面只是讲解一下啊多态 

class A:
    def __init__(self,name):
        self._name = name

    @property
    def name(self):
        return self._name
        
    @name.setter
    def name(self,name):
        self._name = name   

class B:
    def __init__(self,name):
        self._name = name

    def __len__(self):
        return 10

    @property
    def name(self):
        return self._name
        
    @name.setter
    def name(self,name):
        self._name = name   

class C:
    pass


a = A('孙悟空')
b = B('猪八戒')
c = C()


# 定义一个函数
# 对于say_hello()这个函数来说,只要对象中含有name属性,它就可以作为参数传递
#   这个函数并不会考虑对象的类型,只要有name属性即可
def say_hello(obj):
    print('你好 %s'%obj.name)

# 在say_hello_2中我们做了一个类型检查,也就是只有obj是A类型的对象时,才可以正常使用,
# 其他类型的对象都无法使用该函数,hello_2()这个函数就违反了多态
# 违反了多态的函数,只适用于一种类型的对象,无法处理其他类型对象,这样导致函数的适应性非常的差
# 注意,向isinstance()这种函数,在开发中一般是不会使用的!
def say_hello_2(obj):
    # 做类型检查
    if isinstance(obj , A):
        print('你好 %s'%obj.name)  

多态的应用: 

比如 len()  内建函数
之所以一个对象能通过len()来获取长度,是因为对象中具有一个特殊方法__len__,换句话说,只要对象中具有__len__特殊方法,就可以通过len()来获取它的长度。相当于是在len()函数内,会获取__len__方法的返回值。比如上方代码的class B

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值