十二 面向对象

十二 面向对象

1、面向对象简介

▶ Python是一门面向对象的编程语言

▶ 所谓面向对象的语言,简单理解就是语言中的所有操作都是通过对象来进行的

▶ 面向过程:

● 面向对象过程指我们将程序分解为一个一个步骤,通过每个步骤的抽象来完成程序
● 这种编写方式往往只适用于一个功能,如果要实现别的功能,往往复用性比较低
● 这种编写方式符合人类的思维,编写比较容易

1.妈妈穿衣服穿鞋出门
2.妈妈骑上电动车
3.妈妈到超市门口放好电动车
4.妈妈买西瓜
5.妈妈结账
6.妈妈骑电动车回家
7.到家孩子吃西瓜

● 面向对象的编程语言,关注的是对象,而不注重过程,对于面向对象一切皆对象
● 以上方式可以用妈妈给孩子买瓜来解决
● 面向对象比较容易阅读,易于维护,复用性好,但是编写起来比较麻烦

2、类的简介

▶ 类(class):简单理解类就是一张图纸,在程序中我们需要根据类型来创建对象,我们也称对象是类的实例(instance),如果多个对象是通过一个类创建的,我们称这些对象是一类对象。

#a=1  int()  str()   bool   list()......
 a=int(1)   #创建一个int类的实例
 b=str('python')
 print(a,type(a))  
 print(b,type(b))
 #输出:1 <class 'int' >
  python <class 'str'>   

▶自定义的类,类的名字要使用大写字母开头,使用大驼峰命名法

 class MyClass():
    pass
 print(MyClass)
 输出:<class '_main_.MyClass'>

class MyClass():
        pass
#mc就是通过MyClass创建的对象,mc是MyClass的实例    
mc=MyClass()
mc_2=MyClass()
mc_3=MyClass()
mc_4=MyClass()
#mc mc_2 mc_3 mc_4都是MyClass的实例

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

 #print(id(MyClass),type(MyClass))

▶ 我们可以通过对象添加变量,对象添加变量我们称之位属性
▶ 语法:对象.属性名=属性值

mc.name='蜘蛛侠'
print(mc_2.name)

▶ 类的定义:类和对象都是现实生活中事物的抽象
▶ 实际上所有的事物都有两部分构成
1.数据(属性)
2.行为(方法)

#尝试定义一个人类
 class Person():
    #在类的代码块中,我们可以定义变量和函数
    #在类中我们定义的变量,将会成为所有实例的公共属性
    #所有实例都可以访问这些变量
    #a=10
    #b=20
    name='蜘蛛侠'
    #在类中也可以定义函数,类中定义的函数我们称之位方法
    #这些方法可以通过该类的实例来访问
    def speak(a):
        print('hello!')
p1=person()
p2=person()
#print(p1.a)
#print(p2.b)

#调用方法  对象.方法名
#方法调用和函数调用的区别
#如果函数调用,调用的时候有几个形参,就会传递几个实参
#但是如果是方法调用,默认传递一个参数,方法中至少定义一个形参

p1.speak()  #TypeError:没有形参,在def speak(a),加上参数a
p1.speak()
#输出:hello!

#为什么实例对象能够访问到类对象中的属性和方法呢?
#类中定义的属性和方法都是公共的,任何该类的实例都可以访问

▶ 属性和方法的查找流程:
1.当我们调用一个对象的属性时,解析器会在当前对象中寻找是否含有该属性

2.如果有,则直接返回当前对象,如果没有呢,则去当前对象的类对象中去寻找,如果类对象中有则返回对象中的属性值,如果没有,则报错

class Person:
  name='蜘蛛侠'
  def speak(a):
  print('你好我是%s'%.name)  #NameError:name 'name' is not defined
p1=Person()
p2=Person()
p1.name='钢铁侠'      
p2.name='緑巨人'
p1.speak()
p2.speak()
    
class Person:
      name='蜘蛛侠'
      def speak(a):
      print('你好我是%s'%.p1.name)  
p1=Person()
p2=Person()
p1.name='钢铁侠'      
p2.name='緑巨人'
p1.speak()
p2.speak()
输出:你好我是钢铁侠
      你好我是钢铁侠
     
class Person:
      name='蜘蛛侠'
      def speak(a):
      print('你好我是%s'%.a。name)  
p1=Person()
p2=Person()
p1.name='钢铁侠'      
p2.name='緑巨人'
p1.speak()
p2.speak() 
#输出:你好我是钢铁侠
       你好我是緑巨人

▶ 方法每次调用时,解析器都会自动传递一个参数
▶ 第一个参数,就是调用方法的本身
▶ 如果p1调用,第一参数就p1对象
▶ 如果p2调用,第一个参数就是p2对象
▶ a可以是任意参数,一般习惯把这个参数命名为self

3、类的特殊方法

▶例子:
class Person:
    name='葫芦娃'
    def speak(self):
         print('大家好,我是%s'$self.name)
p1=Person()
p2=Person()
p.1speak()
p.2speak()
输出:大家好,我是葫芦娃
      大家好,我是葫芦娃
      
class Person:
    #name='葫芦娃'
    def speak(self):
         print('大家好,我是%s'$self.name)
p1=Person()
#手动添加属性
p1.name='钢铁侠'
p2=Person()
p2.name='蜘蛛侠'
p.1speak()
p.2speak()
输出:大家好,我是钢铁侠
      大家好,我是蜘蛛侠
 
#通过观察我们发现了一些问题
#1.对于Person类来说,name是必须的
#2.对于这个name属性又是不同的
#我们希望在创建对象时,必须设置name属性,如果不设置对象无法创建

class Person:
    #在类中可以用特殊方法,如__开头和__结尾
    #特殊方法不需要我们自己调用
    def __init__(self):
            print('hello')
    def speak(self):
         print('大家好,我是%s'$self.name)
p1=Person()
p1.__init__()
输出:hello
      hello

class Person:
    #在类中可以用特殊方法,如__开头和__结尾
    #特殊方法不需要我们自己调用
    def __init__(self):
            print('hello')
    def speak(self):
         print('大家好,我是%s'$self.name)
p1=Person()
#p1.__init__()
输出:hello

class Person:
    #在类中可以用特殊方法,如__开头和__结尾
    #特殊方法不需要我们自己调用
    def __init__(self,name):
        self.name=name
    def speak(self):
         print('大家好,我是%s'%self.name)
p1=Person('蜘蛛侠')
输出:蜘蛛侠

class Person:
    #在类中可以用特殊方法,如__开头和__结尾
    #特殊方法不需要我们自己调用
    def __init__(self,name):
        self.name=name
    def speak(self):
         print('大家好,我是%s'%self.name)
p1=Person('蜘蛛侠')
p1.speak()
输出:大家好,我是蜘蛛侠

▶ 创建流程:
   p1=Person()
   1.创建一个变量
   2.在内存中创建一个新的对象
   3.执行类中的代码块(只执行一次)
   4.__init__(self)方法执行
▶  类的基本结构
  '''
   class 类名([副类 ]):
        公共属性...
        #对象的初始化方法
        def __init__(self,......):   #这里前后是双下滑线
             代码块
        #其它方法
        def m1(self,......):
            代码块
        def m2(self,......):
            代码块          
       ......
  '''      

4、封装的引入

▶ 出现封装的原因:我们需要一种方式来增强数据的安全性。
1.属性不能随意修改
2.属性不能改为任意值

▶封装是面向对象的三大特征之一

▶封装是指隐藏对象中一些不希望被外部所访问的属性或方法
例子:

 class Dog:
        def__init__(self,name):
              self.name=name
      d=Dog('德牧')
      输出:德牧
      d.name='二哈'    #对name进行了修改
      输出;二哈

    class Dog:
        def__init__(self,name):
              self.hidden_name=name 
        def speak(self):
            peint('大家好,我是%s'%self.hidden_name) 
      d=Dog('德牧')
      d.name='二哈'     #将对象属性名改成一个外部不知道的名字
      d.speak()
      输出:大家好,我是德牧

▶ 我们也可以提供给一个getter()和setter()方法是外部可以访问到属性
1.getter()获取对象中指定的属性
2.setter()用来设置对象指定的属性

class Dog:
def__init__(self,name):
      self.hidden_name=name
 def get_name(self):
       return self.hidden_name
 def set_name(self,name)
       self.hidden_name     
d=Dog('德牧')

▶ 使用封装,确实增加了类的定义的复杂程度 但是它也确保了数据的安全

  1.隐藏属性名,使调用者无法随意修改对象中的属性。
  2.增加了getter()和setter()方法,很好控制属性是否是只读的
 3.使用setter()设置属性,可以增加数据的验证
 4.使用getter()方法获取属性,使用setter()方法设置属性,可以在读取属性和修改属性的同时做一些其他的处理。

▶可以为对象的属性使用双下滑线开头__xxx。双下滑线开头的属性,是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过对象访问

class  Person:
  def __init__(self,name):
        self.hidden_name=name
  def get_name(self):
       return self.hidden_name
  def set_name(self,name)
      self.hidden_name=name
p=Person('蜘蛛侠')
#输出:蜘蛛侠

p.set_name('钢铁侠')
#输出:钢铁侠

p.hidden_name='緑巨人'
#输出:緑巨人             

▶ 其实隐藏属性只不过是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(__name)
#输出:错误,找不到name
p.__name='緑巨人'
print(p.get_name())
#输出:蜘蛛侠
p._Person__name='緑巨人'
print(p.get_name())
#输出:緑巨人

▶一般情况下,使用_开头的属性都是私有属性,没有特殊条件情况下不要修改私有属性

5、property装饰器

▶ 我们可以使用@property装饰器来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性,可以与所定义的属性配合使用,这样可以防止属性背修改。
例子:

class Person:
  def __init__(self,name):
        self._name=name
  def name(self):
      #这是一个getter()的方法
      return self._name
p=Person('葫芦娃')
print(p.name())
输出:葫芦娃

class Person:
      def __init__(self,name):
            self._name=name
      @property     
      def name(self):
          #这是一个getter()的方法
          return self._name
p=Person('葫芦娃')
print(p.name())   
输出:TypeError::'str ' object  is not callable

 class Person:
      def __init__(self,name):
            self._name=name
      @property     
      def name(self):
          #这是一个getter()的方法
          print('get方法执行了')
          return self._name
p=Person('葫芦娃')
p.name='钢铁侠'
print(p.name)
输出:get方法执行了
      葫芦娃   

class Person:
      def __init__(self,name):
            self._name=name
      @property     
      def name(self):
          #这是一个getter()的方法
          print('get方法执行了')
          return self._name
      @name.setter  
      def set_name(self,name):
           self._name=name
p=Person('葫芦娃')
p.name='钢铁侠'
print(p.name)
输出:get方法执行了
      钢铁侠   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值