zoukankan      html  css  js  c++  java
  • 面向对象回顾

    面向过程与面向对象

    面向过程:

    核心是过程二字,指的是解决问题的步骤,根据某个业务的流程,以流水线的思维方式编写程序

    优点:复杂问题流程化,设计思路清晰

    缺点:扩展性差,改变了其中一个环节,就会影响其他环节

    面向对象:

    对象是特征与技能的封装,利用对象具有的属性和方法来实现对象间的交互。

    例子,英雄联盟游戏中,各个英雄具生命值,攻击力等属性;拥有攻击这个技能(在编程时表现为方法)。利用对象的交互来实现游戏的开发。

    优点:扩展性强,各个对象具有的属性是相互独立的,改变一个并不会影响其它

    缺点:复杂度高于面向过程

    类和对象

    什么是类:

    类是对一系列具有相似属性和技能对象的抽象。

    例子,学生都具有姓名,年龄,性别等特征,具有听课,做题等技能。那么把这些相似的特征与技能抽象出来就构成了一个学生类。

    为什么要使用类:

    # 例子
    class Student:
    	job = 'student'
    	def __init__(self, name, age, gender):
    		self.name = name
    		self.age = age
    		self.gender = gender
    	def learn(self):
    		print(f'{self.name} is learning')
    		
    st1 = Student('st1', 18, 'male')
    st2 = Student('st2', 19, 'female')
    st1.learn()
    st2.learn()
    
    # 假如没有类
    # 伪代码
    st1.name = 'st1'
    st1.age = 18
    st1.gender = 'male'
    st2.name = 'st2'
    ....
    
    

    类就是对象的模具,利用模具可以很方便的生产出相似的对象。简单说就是可以减少代码冗余,方便修改。

    现实中的模具生产出的对象都是一样的,我们可以利用__init__方法传入参数,产生出既有相同属性却又具有各自属性值的对象。

    继承

    继承是子类与父类之间的关系(类与对象:实例化)

    什么是继承:

    子类直接继承父类的属性

    为什么要使用继承

    # 回到学生类的例子
    # 假如还要定义老师类,工作人员类,。。。
    # 他们同样都具有name, age, gender的属性
    # 可先定义一个People类
    class People:
        def __init__(self, name, age, gender):
                self.name = name
                self.age = age
                self.gender = gender
    class Student(People):
    	# __int__方法会继承于People类,
    	pass
    class Teacher(People):
    	pass
    s = Student('st1', 18, 'male')
    t = Teacher('t1', 20, 'female')
    

    父类就是子类的模具,利用模具可以很方便的生产出相似的子类。简单说就是也是可以减少代码冗余,方便修改。

    派生

    如何在继承父类的同时,又让子类具有自己的属性:使用派生

    派生的方法:

    1. 直接定义新的属性
    2. 重用父类方法
    # 例子:1. 直接定义新的属性
    # 让Student类继承People的同时又具有learn的方法和job属性
    # 让Teacher类继承People的同时又具有teach的方法和job属性
    class Student(People):
    	job = 'student' # 直接定义一个job属性
    	def learn(self): # 直接定义一个learn方法
    		print(f'{self.name} is learning')
    class Teacher(People):
    	job = 'teacher'
    	def teach(self):
    		print(f'{self.name} is teaching')
    
    # 例子:2. 重用父类方法
    # 让Teacher继承People类的say_hello方法介绍自己的姓名,同时又介绍自己的角色
    class People:
        def __init__(self, name, age, gender):
                self.name = name
                self.age = age
                self.gender = gender
        def say_hello(self):
            print(f'hello every one!')
            print(f'my name is {self.name}.')
    class Teacher(People):
    	job = 'teacher'
    	def teach(self):
    		print(f'{self.name} is teaching')
        def say_hello(self): 
            super().say_hello() # 重用People类的say_hello方法
            print(f'my job is {self.job}') # 加上介绍自己角色的功能
            # People.say_hell(self) # 另外一个调用父类方法的方式,要传入self参数(如果是绑定到对象的方法的话)
    

    组合

    组合是对象和对象的关系,具体说是一个对象包含另外一个对象

    # 例子学生对象包含一个课程对象
    class Course:
        def __init__(self, name, period):
            self.name = name
            self.period = period
    python = Course('python', 6)
    s = Student('st1', 18, 'male')
    s.course = python # 让学生对象包含了一个课程对象
    s.cousre.name # 查看课程名称
    s.cousre.period # 查看课程周期
    
    

    小结:继承,派生,实例化,组合

    1. 子类继承父类,类实例化产生对象:父类-->子类-->对象
    2. 子类继承父类时可以通过派生的方法产生自己的属性
    3. 一个对象可以包含其他不同类的对象,如学生对象包含了课程对象,这种思想叫组合

    封装

    什么是封装

    把相关联的数据或方法属性放到一起,并提供有限的访问接口,隐藏某些仅供内部使用的私有属性。

    例子:把属性封装到对象中,把一些函数和数据封装到模块中

    Python中如何隐藏私有属性

    # 在属性名前面加上双下划线 __x, 会自动变形为_类名__x的形式
    # 例子(伪代码),利用前面选课系统中的Base类和db_handler
    # V0, 不隐藏salary属性
    class Teacher(Base):
        def __init__(self, name, salary):
            self.name = name
            self.salary = salary # 不隐藏salary属性
            self.save()
        @classmethod
        def select(cls, name):
            return db_handler.select(cls, name) 
            
    t = select('teacher1') 
    t.salary = 20000 # 可直接修改
    
    # V1 不允许修改salary,只提供查看的接口,使用__salary隐藏属性
    class Teacher(Base):
        def __init__(self, name, salary):
            self.name = name
            self.__salary = salary # 隐藏salary属性
            self.save()
        def get_salary(self): # 提供一个查看salary的接口
            return self.__salary 
        @classmethod
        def select(cls, name):
            return db_handler.select(cls, name)
            
    t = select('teacher1') 
    # t.salary = 20000 # 现在不能在外部使用这种方法改变salary
    print(t.get_salary()) # 只提供了一个查看的salary的接口
    
    # 进阶补充 如何使得查看salary不使用一个方法t.get_salary()来查看,而使用t.salary的方法查看:使用property装饰器
    # V2 使用property装饰器,隐藏salary属性的同时,提供t.salary的方式查看
    class Teacher(Base):
        def __init__(self, name, salary):
            self.name = name
            self.__salary = salary # 隐藏salary属性
            self.save()
        @property
        def salary(self): # 提供一个查看salary的接口
            return self.__salary 
        @classmethod
        def select(cls, name):
            return db_handler.select(cls, name)
    t = select('teacher1') 
    # t.salary = 20000 # 依然不能在外部使用这种方法改变salary
    print(t.salary) # 但可以用t.salary查看,提供了一个更加自然的访问私有属性的方法,对比t.get_salary()方法
    
    
    

    小结:封装,Python访问控制机制,property装饰器

    1. 封装只是一个思想,比如类对属性的封装,模块对数据和函数封装。
    2. 封装可以理解为两层含义:a. 把东西封装起来,b. 控制私有属性的访问和修改,同时提供必要的接口
    3. Python中可以使用 __属性 的方式隐藏属性,但在python中并不是强制性的。依然可以通过 对象._类名__属性名 访问或修改
    4. 在python中可以用property这个工具,使得可以隐藏私有属性的同时,提供一个优雅的查询方式(对比:t.get_salary() 和t.salary)

    多态性

    什么是多态性

    # 例子, 伪代码
    cat.speak() # miao miao ~
    dog.speak() # wang wang ~
    cow.speak() # mou mou ~
    

    用同一个方法名称调用,却又有不同的效果,表现为多种不同的形态

    如何实现多态

    # 1. 使用继承抽象类
    import abc
    from abc import abstractmethod
    
    class Animal(metaclass=abc.ABCMeta):
    	@abstractmethod
    	def speak(self):
    		pass
    class Cat(Animal):
        def speak(self): # 必须定义speak, 否则实例化时会报错
            print('miao miao ~') 
    class Dog(Animal):
        def speak(self): # 必须定义speak, 否则实例化时会报错
            print('wang wang ~') 
    c = Cat()
    d = Dog()
    c.speak()
    d.speak()
    		
    
    # 2. 使用鸭子类型
    class Cat: # 不再继承于某个特定的类
        def speak(self): # 用一个统一的函数名来表示动物叫这个方法
            print('miao miao ~') 
    class Dog:
        def speak(self): # 用一个统一的函数名来表示动物叫这个方法
            print('wang wang ~') 
    c = Cat()
    d = Dog()
    c.speak()
    d.speak()
    

    什么是鸭子类型:不是一个具体的类,如果某些对象都具有统一的调用方法,我们可以说他们属于同一个鸭子类型。在上个例子中我们可以说Cat和Dog都属于 Animal这样一个鸭子类型(但我们并没有定义Animal, 也没有使用继承,只是我们编写程序时让他们具有了统一的speak方法,看起来像属于同一个类型)

    小结:多态性,抽象类和鸭子类型

    1. 多态性也只是面向对象编程中的一种思想,简单的说就是不同对象有相同的调用方法,却会产生不同的调用结果
    2. 在python中可以用抽象类和鸭子类型实现多态性
    3. 在python中推荐使用鸭子类型,而不推荐使用抽象类。
  • 相关阅读:
    __doPostBack的使用
    【转】function,new,constructor and prototye
    谈谈一些网页游戏失败的原因到底有哪些?(转)
    全面剖析页游巨头发家史(转)
    2013.02.20开通博客
    老子喜欢的女人
    如何成为强大的程序员?(转)
    注重健康
    学习方法总结
    数据库知识点滴积累
  • 原文地址:https://www.cnblogs.com/1012zlb/p/12063332.html
Copyright © 2011-2022 走看看