python 面向对象-继承、封装和多态

1、面向对象的三大特性:

继承、封装和多态

2、继承

  • 语法:class Student(父类):
  • 变量可以被继承
  • #coding=utf-8
    import  test9
    class Student(test9.Person):
        sum = 0
        def __init__(self,name,age): #构造函数
            self.name = name
            self.age  = age
        def do_homework(self):#实例方法
            self.do_english_homework()
            print(self.name +" do homework")
    
        def do_english_homework(self):
            print(self.name+ " do english homework")
        def __marketing(self,score):
            if score < 0:
                return 
            else:
               self.score = score
            print (self.name+" score :" + str(score)) 
  • 将一些应该父类拥有的属性,放到父类
  • class Person():
        def __init__(self,name,age): #构造函数
            self.name = name
            self.age  = age
        def getName(self,name):#实例方法
            self.name = name
            print(self.name)

    这个是子类

  • #coding=utf-8
    from test9 import  Person
    
    class Student(Person):
        sum = 0
        # def __init__(self,name,age): #构造函数
        #     self.name = name
        #     self.age  = age
        def do_homework(self):#实例方法
            self.do_english_homework()
            print(self.name +" do homework")
    
        def do_english_homework(self):
            print(self.name+ " do english homework") 
        
    student1 = Student("anson",19)
    print(student1.__dict__)

    输出

  • [Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"
    {'age': 19, 'name': 'anson'}

    这说明,变量是可以被继承的。

  • 方法可以被继承
  • #coding=utf-8
    from test9 import  Person
    
    class Student(Person):
        sum = 0
        # def __init__(self,name,age): #构造函数
        #     self.name = name
        #     self.age  = age
        def do_homework(self):#实例方法
            self.do_english_homework()
            print(self.name +" do homework")
    
        def do_english_homework(self):
            print(self.name+ " do english homework") 
        
    student1 = Student("anson",19)
    student1.getName()
    # [Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"
    # anson
  • 和Java一样,python也是单继承
  • 父类构造函数和子类构造函数
  • 子类构造方法中显式调用父类构造方法
#coding=utf-8
from test9 import  Person

class Student(Person):
    sum = 0
    def __init__(self,school):
        self.school = school

    def do_homework(self):#实例方法
        self.do_english_homework()
        print(self.name +" do homework")

    def do_english_homework(self):
        print(self.name+ " do english homework") 
    
student1 = Student("anson")
student1.getName()

输出:报错

[Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"
Traceback (most recent call last):
  File "/Users/anson/Documents/Project/python_ToolCodes/test8.py", line 17, in <module>
    student1.getName()
  File "/Users/anson/Documents/Project/python_ToolCodes/test9.py", line 7, in getName
    print(self.name)
AttributeError: Student instance has no attribute 'name'

报错原因是缺少父类的构造函数的属性,即然是学生,那肯定也是人,也是要有姓名和年龄的

所以需要改写成:

#coding=utf-8
from test9 import  Person

class Student(Person):
    sum = 0
    def __init__(self,school,name,age):
        self.school = school
        #Person.__init__(name,age)#显示调用父类构造函数,显然是不行的
        Person.__init__(self,name,age)#手动传入self
    
    def do_homework(self):#实例方法
        self.do_english_homework()
        print(self.name +" do homework")

    def do_english_homework(self):
        print(self.name+ " do english homework") 
    
student1 = Student("yangzte","anson",19)
student1.getName()
# [Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"
# anson

问题1:子类构造方法中,显示调用父类的构造方法就可以了,且用父类名就可以了

问题2:为什么需要必须显示的传入self呢?前面说的self 是python自动给我们传的。

一个类调用一个实例方法,本身不伦不类,但是python就是可以这么干,所以

 Person.__init__(self,name,age)#手动传入self

显示调用父类构造方法可以这么干

那为什么必须传self呢?

因为如果我们new 个对象,其实是python 隐式调用了构造方法,但是self 它也是帮我们传入了的,只是我们看不见。

包括我们用对象去调用构造方法,也是不传self的,实质上,对象就是self,python是知道的,所以对象调用构造方法或者是实例方法时,对象.构造方法(),或者对象.实例方法(),python自己就把“对象”当成self 传给构造方法__init__(self, , ,)或者实例方法(self,,,)

但是用个类去调用一个构造方法,python都不知道具体对象到底是谁,那它就认为,跟调用普通方法没什么区别,普通方法要传全部必须参数,那这里也得着么传全了

能力有限,解释只能解释到这个肤浅的层面了

  • 子类构造方法中隐式调用父类构造方法

 

  • super(Student,self).__init__(name,age)#隐式调用父类构造函数;显然报错了
这是为什么呢?解答在这里
https://blog.csdn.net/andos/article/details/8973368

 

  • #coding=utf-8
    from test9 import  Person
    
    class Student(Person):
        sum = 0
        def __init__(self,school,name,age):
            self.school = school
            #Person.__init__(name,age)#显式调用父类构造函数,显然是不行的
            #Person.__init__(self,name,age)#手动传入self是可以的
            super(Student,self).__init__(name,age)#隐式调用父类构造函数,
        
        def do_homework(self):#实例方法
            self.do_english_homework()
            print(self.name + " do homework")
    
        def do_english_homework(self):
            print(self.name+ " do english homework") 
        
    student1 = Student("yangzte","anson",19)
    student1.getName()
    
    # [Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"
    # Traceback (most recent call last):
    #   File "/Users/anson/Documents/Project/python_ToolCodes/test8.py", line 19, in <module>
    #     student1 = Student("yangzte","anson",19)
    #   File "/Users/anson/Documents/Project/python_ToolCodes/test8.py", line 10, in __init__
    #     super(Student,self).__init__(name,age)#隐式调用父类构造函数,
    # TypeError: super() argument 1 must be type, not classobj

    要怎么解决呢?

  • 看看原来的父类
  • #coding=utf-8
    class Person():
        def __init__(self,name,age): #构造函数
            self.name = name
            self.age  = age
        
        def getName(self):#实例方法
            print(self.name)
  • 其实就是父类如果是无源之水,那就会报错,比如student的父类也得是从别的父类继承,即使是继承自万物之源Object 类 ,那也是必须的
class Person(object):在这句,传入了object类
  • #coding=utf-8
    class Person(object):
        def __init__(self,name,age): #构造函数
            self.name = name
            self.age  = age
        
        def getName(self):#实例方法
            print(self.name)

输出:不报错了

  • [Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"
    anson

     

posted @ 2020-08-05 18:08  XiaoLee-C  阅读(237)  评论(0编辑  收藏  举报