梦想一步登天

导航

python--面向对象之三个特性:封装、继承、多态

一、面向对象简介

1、面向对象不是所有的情况都适用
2、面向对象编程
  a.定义类
    class 类名:
      def 方法1(self, 参数名):
        方法体

  b.根据类创建对象,使用对象去执行类中的方法
    obj = 类名()
    obj.方法名
3、self,形参,python内部传递

4、函数式编程与面向对象式编程的区别


示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
面向对象编程初识
"""
#先定义一个类
class Hello():
#定义一个方法
  def sayHell(self, name):
  print('欢迎您!' + name)
#创建一个对象
obj = Hello()
obj.sayHell('yusheng_liang')

 

二、面向对象--封装
应用场景:
  1、当同一类型的方法具有相同参数时,直接封装到对象即可
  2、把类当做模板,创建多个对象(对象内封装的数据可以不一样)

  3、类名+括号
    自动执行类中的__init__方法:创建了一个对象
    在__init__方法中执行具体封装的操作
    __init__有一个特殊名字:构造方法(初始化)

示例一:面向对象之封装,非主流的方式

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
封装,非主流的方式
"""
class Foo():
  def add_foo(self):
  print(self.name) #打印已经封装好的对象属性
def del_foo(self):
  print(self.name)

#创建一个对象
obj1 = Foo()
#在对象中封装数据
obj1.name = 'yusheng_liang'
#执行方法,执行过程中可以根据self去obj1中取已经封装在里面的数据
obj1.add_foo()


示例二:面向对象之封装,使用构造方法的方式封装数据

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
封装,使用构造方法的方式封装数据
"""
class Foo():
def __init__(self, args):
  """
  构造方法
  :param args:
  """
  self.name = args

def add_foo(self):
  print(self.name) #打印已经封装好的对象属性
def del_foo(self):
  print(self.name)

#创建一个对象,实例,并且将yusheng_liang封装到对象中
obj1 = Foo('yusheng_liang')

# #在对象中封装数据
# obj1.name = 'yusheng_liang'

#执行方法,执行过程中可以根据self去obj1中取已经封装在里面的数据
obj1.add_foo()

 

三、面向对象--继承

  1、派生类可以继承基类中所有的功能
  2、派生类和基类同时存在相同的功能时,优先找派生类的
  3、python类可以同时继承多个类(C#/java不可以),用逗号隔开,优先找自己的功能,再在继承类中从左到右的顺序查找功能

  4、多继承时的查找顺序如下:

示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
面向对象之继承
"""
#定义一个父类,又叫基类
class Animals:
  def say(self):
  print('Hello, I am saying')
def run(self):
  print('I am running')

#定义子类,又叫派生类,在括号中写上父类名
class Cat(Animals):
  def __init__(self, name):
    self.name = name

  def sing(self):
    print(self.name + ' 喵喵喵')

#定义子类,又叫派生类,在括号中写上父类名
class Dog(Animals):
  def __init__(self, name):
    self.name = name

  def sing(self):
    print(self.name + ' 汪汪汪')

cat1= Cat('小猫咪')
cat1.sing()
cat1.say()

dog1 = Dog('小狗狗')
dog1.sing()
dog1.run()

示例结果:


四、面向对象--多态,多种形态
  python本身支持多态

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
多态
"""

class Foo:
  def f1(self):
    print('Foo')

class Bar:
  def f1(self):
    print('Bar')

  def func(arg):
    print(arg)

func(Foo())
func(Bar())

 

补充:
  查找源码的过程(self.xxxx(), 从底层开始找)
  执行父类的构造方式:
    super(当前类, self).init()
    父类.__init__(self,xxx)


五、面向对象的进阶

5.1、利用反射查看面向对象成员归属

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 """
 4 利用反射查看面向对象成员归属
 5 """
 6 
 7 class Foo:
 8 
 9   def __init__(self, name):
10     self.name = name
11 
12   def show(self):
13     print('show')
14 
15 # 反射:以字符串的形式去对象(模块)中操作其成员
16 # 当反射对象为一个类时,只能找类里的成员
17 obj = hasattr(Foo, 'show1')
18 print(obj)
19 
20 #当反射的对象为一个对象时,即可以找对象,找类的成员
21 obj1 = Foo('yusheng_liang')
22 ret = hasattr(obj1, 'name')
23 print(ret)
24 ret1 = hasattr(obj1, 'show')
25 print(ret1)

 

5.2、面向对象类成员之静态字段,静态方法,类方法

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
面向对象类成员之静态字段,静态方法,类方法
"""
class Provice:
  #静态字段
  country = "中国"
  def __init__(self, name):
  #普通字段,对象中
    self.name = name

  #普通方法,类中
  def show(self):
    print('show')

  #静态方法,没有self
  @staticmethod
  def static_obj(arg1, arg2):
    print('我是一个静态方法,可以传递任何参数')

  #类方法
  @classmethod
  def class_obj(cls):
    print('我是一个类方法:', cls)

  #特性,将方法伪造成一种字段
  @property
  def end(self):
    tmp = "%s 大大的好" %self.name
    print(tmp)

  #特性的设置值
  @end.setter
  def end(self,value):
    self.name = value

# 1、通过类访问的有:静态字段、静态方法,类方法
print('------1、通过类访问的有:静态字段(每个对象都有一份)、静态方法(无需使用对象封装的内容),类方法------')
print(Provice.country)       #静态字段
Provice.static_obj(1, 2)     #静态方法
Provice.class_obj()      #类方法

print("-------2、通过对象访问的有:普通字段(每个对象都不同的数据),类的方法(普通方法,使用对象中的数据)-----------")
# 2、通过对象访问的有:普通字段,类的方法
obj = Provice("广东")
ret = obj.show()

# 3、特性的访问

print('-------3、特性的访问----------')

obj1 = Provice("China")
ret1 = obj1.end

#设置end的参数值
obj1.end="我被重新设置了值"
print(obj1.end)

实例结果:

 

5.3、面向对象之成员修饰符

成员修饰符:公有和私有
私有的,自己好使,其他的谁都不好使

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
面向对象之成员修饰符
静态字段,普通字段,静态方法,普通方法,类方法,
"""

class Foo:
  xo = "xo"
  __ox = "我是ox"

  def __init__(self, bk):
    self.backend = bk

  def fetch(self):
    print(Foo.__ox)

#静态方法的修饰符调用

obj = Foo('123')
obj.fetch()

 

六、面向对象的特殊成员

6.1、特殊成员--call
实现了__call__方法的对象,相当于重载了(),可以实现调用功能。

1 class A():
2     def __call__(self,name):
3         print("%s is running!" % name)
4 
5 a = A()
6 a("people")
7     

结果:
people is running!

 

6.2、特殊成员之setitem
设置给定键的值

6.3、特殊成员之getitem
返回键对应的值。

6.4、特殊成员之delitem
删除给定键对应的元素。

6.5、特殊成员之iter

 1 class Foo:
 2 
 3     def __iter__(self):
 4         yield 1
 5         yield 2
 6         yield 3
 7 
 8 obj = Foo()
 9 #如果执行for对象时,自动会执行对象的iter方法,生成器    
10 for i in obj:
11 print(i)            

总结:方法的原理就是:当我们对类的属性item进行下标的操作时,首先会被__getitem__()、__setitem__()、__delitem__()拦截,从而进行我们在方法中设定的操作,如赋值,修改内容,删除内容等等。

 

posted on 2019-10-13 23:36  梦想一步登天  阅读(392)  评论(0编辑  收藏  举报