首页 > 代码库 > 面向对象【day07】:多态-面向对象使用场景--知识点回顾

面向对象【day07】:多态-面向对象使用场景--知识点回顾

本节内容

  1. 多态
  2. 面向对象使用场景
  3. 知识点回顾

一、多态

一、概述

  多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
  那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。
  很遗憾,在python不能直接的支持多态,所以我们只能间接的去执行
 

二、多态

其实就是用父类调用子类的方法,根据传入的子类的实例,得知具体调用哪个子类的方法,那在python中如何实现多态呢?代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Animal:
 
    def __init__(self,name):
        self.name = name
 
    def talk(self):
        print("animal {0} is talk".format(self.name))
 
class Cat(Animal):
    def talk(self):
        return "Meow!"
 
class Dog(Animal):
    def talk(self):
        return "Woof!Woof!"
 
def animal_talk(obj):    #定义一个调用类的talk方法
    print(obj.talk())
 
all_animal = [Dog("d1"),Cat("c1")]  #把对象存入列表中
 
for animal in all_animal:  #循环传入对象
    animal_talk(animal)  # 实现类似于Animal.talk(Dog("d1"))这种效果
 
#输出
Woof!Woof!
Meow!

小结:

  1. 多态在python中是不支持的
  2. 想要在python实现类似于Animal.talk(Dog("d1")),可以定义一个可以类方法的一个方法,调用时需要往这个方法传入类的实例

二、面向对象使用场景

一、概述

  之前我们学了面向对象知识,那我们在什么时候用呢?不可能什么时候都需要用面向对象吧,除非你是纯的面向对象语言,好的,我们下面就来谈谈

二、知识回顾

2.1 什么是面向对象?

  在学面向对象之前我们都是用:函数

  面向对象编程其实就是:类 + 对象

2.2 什么是类,什么是对象,它们之前又有什么关系?

1
2
3
4
5
6
7
8
9
10
11
class 类名:
    def 函数1():
        pass
 
    def 函数2():
        pass
 
# obj是对象,是一个实例化的
 
obj = 类名()
obj.函数1()

三、使用场景

3.1 提取公共功能

说明:我们把一些公共的功能,可以提取出来,并且在公共的功能中创建属于这个对象的属性,然后其他的方法就可以使用这个对象的属性了

我们举一个远程上传,执行命令的例子,例子代码如下:

1
2
3
4
5
6
7
8
9
def upload():
    #连接服务器
    #上传文件
    #关闭
 
def cmd():
    #连接服务器
    #执行命令
    #关闭

从上面可以看出,连接服务器和关闭服务时属于公共的功能,我们用面向对象实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class SSH:
     
    def __init__(self,host,port,pwd,username):
           self.host = host
           ....
 
    def connection(self):
           #去创建连接
           self.conn = #和服务器创建的连接对象()
 
    def close(self):
           #关闭
            self.conn.关闭
 
    def upload(self):
            self.conn #使用连接上传文件
 
    def cmd(self):
            self.conn #使用连接执行命令
 
obj = SSH(...)
obj = connection()
obj.upload()
obj.close()

3.2  根据一个模板去创建某些东西

说明:我们用面向对象,其实就是建立一个模板,比如说见一个person类,通过这个person类去实例化很多对象,子类继承它的时候,也可以重用一些属性和方法,这里就不多说了

3.3 多个函数传入共同参数

说明:当很多的函数需要有公共的参数时,可以吧参数提取出来,封装到对象中,便于以后方便使用

比如说,我们有很多的函数,需要用公共的参数,代码如下:

1
2
3
4
5
6
7
8
def f1(host,port,pwd,arg):
    pass
 
def f2(host,port,pwd,arg,arg2):
    pass
 
def f3(host,port,pwd,arg,arg2):
    pass

上面三个函数都用到了host、port、pwd、arg这四个参数,那我们就可以封装到对象中,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class f:
     
    def __init__(self,host,port,pwd,arg):
            self.host = host
            self.port = port
            self.pwd = pwd
            self.arg = arg
         
    def f2(self):
            self.host
             ....
 
    def f2(self,args2):
            self.host
            ....
     
    def f3(self,args2):
            self.host
            ....

 总结:

  1. 我们把一些公共的功能,可以提取出来,并且在公共的功能中创建属于这个对象的属性,然后其他的方法就可以使用这个对象的属性了
  2. 根据一个模板去创建某些东西
  3. 多个函数传入共同参数

三、知识点回顾

一、self关键字

作用:调用当前方法的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Foo:
     
    #静态字段或者公有属性
    country = "中国"
 
    def __init__(self,name,count):
        self.name = name
        self.count = count
 
    def bar(self):
        pass
 
obj1 = Foo("江苏"100000)
obj1.bar

注意:country = "中国" 属于公有字段,它的作用是:每个对象中保存相同的东西时,可以使用静态字段

 技术分享

二、封装

  • 类中封装了 :字段、方法
  • 对象中封装了:普通字段的值
  • 不仅可以封装字段,还可以封装对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class F1:
    def __init__(self,n):
        self.N = n
        print("F1")
     
class F2:
    def __init__(self,arg1):
        self.a = arg1
        print("F2")
 
class F3:
     
   def __init__(self,arg2):
        self.b = arg2
        print("F3")
 
o1 = F1("alex")
o2 = F2(o1)
o3 =F3(o2)
 
######输出alex####
# o3 =F3(o2)
o3 ====> o2
 
# o2 = F2(o1)
o3.b.a
 
# o1 = F1("alex")
o1.b.a.N

三、继承

说明:子类继承父类,对象调用方法时,先从自己的类中去找,找不到,就会去找父类中的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class F1:
    def __init__(self):
        print(‘F1‘)
 
    def a1(self):
        print("F1a1")
 
    def a2(self):
        print("F1a2")
 
class F2(F1):
    def __init__(self):
        print("F1")
 
    def a1(self):
        print("F2a1")
 
    def a2(self):
        self.a2()
        print("F2a2")
 
class F3(F2):
    def __init__(self):
        print("F3")
 
    def a2(self):
        print("F3a2")
 
obj = F3()
obj.a1()
 
#输出
F3a2
F2a1

上面代码访问的顺序如下:

  1.  先去到F3中找a1方法,没有找到
  2. 到F2父类去找,找到了a1方法,去执行a1方法
  3. 执行过程中需要调用F3中的a2方法

四、静态方法

4.1 类的组成

  • 字段:1.普通字段(保存在对象中),2静态字段(保存在类中)
  • 方法:普通方法(保存在类中,用对象去调用)
1
2
3
4
5
6
7
class F1:
    age = 18  #静态字段
    def __init__(self,name):
        self.name = name  #普通字段
 
    def a1(self):   #普通方法
        print(‘F1a1‘)

4.2 静态方法

特点:

  1. 保存在类中
  2. 调用者无需创建对象
  3. 可以有任意个参数
1
2
3
4
5
6
7
8
class F1:
     
    @staticmethod   #声明是静态方法
    def a1(n1,n2):   #无需传入对象,但是可以声明多个值
        print(‘xiaogao‘)
 
 
F1.a1(1,2)   #类名.方法名 方式调用

作用:当对象不需要传入参数时,去创建对象有些浪费,占着资源,所以还不如直接用类名直接去调用,这个类似于函数。

面向对象【day07】:多态-面向对象使用场景--知识点回顾