欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python继承

程序员文章站 2022-03-19 13:26:31
面向对象三大特征:封装、继承、多态1.继承面向对象编程 (OOP) 语言的一个主要功能就是“继承”,所谓继承就是使现有的类无需编码便可以拥有原有类的方法和属性。被继承的类可以称之为***父类、基类、超类***。继承的类可以称之为***子类、派生类***。派生和继承是一体两面,从父类向子类看就是派生,从子类向父类看就是继承。子类和父类的关系可以用“is a”类表示,即子类是父类的一种,是一个更具体、更加强大的父类。python支持单继承和多继承。继承的优点:可以简化代码,减少冗余度提高了代码的可...

面向对象三大特征:封装、继承、多态

1.继承

面向对象编程 (OOP) 语言的一个主要功能就是“继承”,所谓继承就是使现有的类无需编码便可以拥有原有类的方法和属性。

被继承的类可以称之为***父类、基类、超类***。继承的类可以称之为***子类、派生类***。派生和继承是一体两面,从父类向子类看就是派生,从子类向父类看就是继承。子类和父类的关系可以用“is a”类表示,即子类是父类的一种,是一个更具体、更加强大的父类。python支持单继承和多继承。

继承的优点:

  • 可以简化代码,减少冗余度
  • 提高了代码的可维护性
  • 提高了代码的安全性

1.1 单继承

所谓的单继承就是一个子类只有一个父类。子类会继承父类所有的属性和方法。

  • 私有成员在子类中无法直接使用
  • 子类对象无法直接使用继承自父类的私有成员
  • 子类方法和父类方法重名,通过子类对象调用的是子类方法
#语法:
class 子类名(父类名):
    pass

注意:object是Python中所有类的父类【一般情况下,如果一个类没有指明的父类,默认它的父类为object】

  • 构造函数的继承

    class Animal:
        def __init__(self,name,age):
            self.name = name
            self.__age =age
    	....
    
    class Dog(Animal):
        def __init__(self,name,age,gender):
            #调用父类构造方法的好处,简化了子类构造方法代码,实现了代码复用
            #1. super(当前类名,self).__init__(实参列表) #实参不要带self
            # super(Dog,self).__init__(name,age)
            # 2. super().__init__(实参列表)#实参不要带self
            # super().__init__(name, age)
    
            #3. 父类名.__init__(self,其它参数)
            Animal.__init__(self,name,age)
            self.gender = gender
    	....
    
  • 方法的改写

    class Animal:
        def __sleep(self):
            print('睡饱饱')
        def eat(self):
            print('吃饭饭')
        def sleeping(self):
            self.__sleep()
    	....
    class Dog(Animal):
    	#改写继承自父类的方法
        def eat(self):
            # Animal.eat(self)
            super().eat()
            print('香香的大骨头')
        #添加新方法
        def bark(self):
            print('别跑,爷咬不死你')
            # print(self.age)
    dog = Dog('泰迪',5,'公')
    dog.eat()  #优先调用子类方法
    dog.sleeping()  #子类没有,则调用父类方法,一直找到object都没有,则报错
    
  • 方法添加

1.2 多继承

一个子类可以有多个父类。语法:

class 子类类名(父类1,父类2....):
	子类类体

2.类成员

类成员包括:类属性和类方法,不同于成员属性和成员方法属于对象,类属性和类方法属于类,可以不实例化对象,直接通过类名调用,这些类成员为所有对象共有,一般用于对象间通信。

  • 在程序运行期间类属性始终存在

  • 类属性

    class Person:
        #类属性
        name = '无名氏'
        gender = '男'
        __age = 0   #私有类属性
    
        def __init__(self,name,age):
            self.name = name  #实例属性或成员属性
            self.__age = age
    
    #实例化对象
    zhang = Person('张三',20)
    #类属性调用方式  
    #调用方式:类名.属性名  对象.属性名
    print(Person.name)  #类属性可以不实例化对象调用
    print(zhang.gender)
    
    print(Person.__age)  # 私有类属性不能通过类名直接调用
    #访问的优先级  成员属性高于类属性
    #如果成员属性名和类属性名冲突,优先访问成员属性,成员属性屏蔽类属性
    #应该尽量避免成员属性和类属性重名
    print(zhang.name)  #张三
    
    #删除对象的属性
    del zhang.name
    print(zhang.name)  #无名氏  访问的是类属性 
    
  • 类方法和静态方法

    • 类方法属于类,为所有对象共有,可以通过类名或对象调用
    • 类方法可以用来访问类属性
    • 静态方法属于类的作用域内的全局函数
    • 类方法和静态方法的区别,类方法第一个参数是类对象,由系统传入,静态方法没有
    • 共同点:静态方法和类方法都可以通过类名直接调用,属于类,不属于对象
class Date:
      def init(self,year,month,day):
          self.year = year
          self.month = month
          self.day = day
          
      @classmethod     #类方法
      def date_from_string(cls,date_string):
          '''
          :功能:根据传入字符串创建日期对象
          :param cls 类对象,和类名作用一样
          :param date_string: 日期字符串,格式必须是yyyy-mm-dd
          :return: 日期对象
          '''
          year,month,day = tuple(map(int,date_string.split('-')))
          return cls(year,month,day)

      @staticmethod
      def is_valid_date(date_string):
          year,month,day = tuple(map(int,date_string.split('-')))
          return year >= 0 and 1 < month <= 12 and 0< day <=31

  d1 = Date.date_from_string('2018-05-29')
  print(d1.year,d1.month,d1.day)
  print(Date.is_valid_date('2018-5-29'))

3 实例成员的动态绑定(了解)

实例的属性和方法都可以动态绑定,也就是可以在程序运行期间可以给程序增加功能,这对于那些静态语言来说无异于天方夜谭,但对python来说一切皆有可能

  • 给对象动态添加的属性只属于这个对象,其它对象没有该属性
  • 使用__ slots__限制属性的动态绑定:
class Cat:
    __slots__ = ('gender','name','age','kind')  #这个类的对象这能有这些属性
	
cat = Cat()

#1.动态绑定属性
cat.name = 'tom'
cat.gender = '公'  #动态添加的属性
#cat.weight = 8  #不能添加这个属性,语法错误

定义一个函数,第一个参数要是self
def walk(self):
    print(self.name)
    
cat.walk = walk
cat.walk(cat)  #怪胎

#2.给对象绑定方法
from types import  MethodType  #引入types模块中的MethodType
cat.walk = MethodType(walk,cat)   #给cat对象绑定walk方法
cat.walk()


#3.给类绑定实例方法 ,所有对象都可以使用
Cat.walk = walk
cat1 = Cat()
cat1.name = 'jerry'
cat1.walk()

4. 系统魔术方法

4.1 __init____new__

  • __ new__ 用于创建一个对象,有返回值;__new__是类方法;__ init__ 用于初始化对象,没有返回值

  • __new__默认参数是cls,系统传递的是类名,__init__默认参数是self,系统传递的是当前对象

  • __ new__ 先于__ init__ 执行

    class Dog:
        def __new__(cls, *args, **kwargs):
            print('new方法在执行')
           // return super().__new__(cls,*args, **kwargs)   #必须通过父类的__new__创建对象
            return object.__new__(cls,*args, **kwargs)
            
        def __init__(self,name,age):
            self.name = name
            self.__age = age
            print('init方法在执行')
    

4.2 算数运算符重载

在python中自定义类的对象也可以象系统类型一样完成+、-、*、/、索引、切片等运算,这有赖于python类有运算符重载功能。

class MyTime:

    def init(self,hour,minute,second):
        self.hour = hour
        self.minute = minute
        self.second = second
    def __add__(self, other):
        if not isinstance(other,self.class):
            raise TypeError('Not a MyTime')
        second = self.second + other.second
        minute = self.minute + other.minute + second // 60
        hour = (self.hour + other.hour + minute // 60) % 24
        return self.__class__(hour,minute % 60,second % 60)
    #+=
    def __iadd__(self, other):
        self = self.__add__(other)
            
    def __str__(self):
       return "{}:{}:{}".format(self.hour,self.minute,self.second)
            
t1 = MyTime(5,34,45)
t2 = MyTime(8,45,34)
res = t1 + t2  #t1.__add__(t2)
print(res)
t1 += MyTime(3,20,10)
print(t1)

4.3 迭代器

如果想让一个类用于for-in 循环则必须实现__ iter__ 和__ next__ 方法

class Fib:
    def __init__(self):
        self.x = 0
        self.y = 1
    def __iter__(self):
        return  self  #返回当前对象
    def __next__(self):
        self.x ,self.y = self.y, self.x + self.y   #迭代公式
        if self.x > 1000:
            raise StopIteration()
        return  self.x 

4.4 __call__

​ 如果一个类实现了__call__(slef, [,*args [,**kwargs]])方法,则该类的对象可以象函数一样调用。它是实现类装饰器的基础

class Demo:
    def __call__(self, *args, **kwargs):
        print("我是函数,不过是假冒的")

d1 = Demo()
d1()
  • 类装饰器
class Decrator:
    def __call__(self, func):
        def inner():
            func()
            print("*"*50)
        return inner

@Decrator()
def test():
    print("我是你们的小可爱")

5.单例设计模式

2.1、设计模式概述

  1. 概念:对特定问题的一种解决方案,和平台、语言无关
  2. 作用
    • 更好的理解面向对象
    • 让你的代码更加优雅
    • 使你的代码更加容易扩展和复用
    • 面试时候的重点

设计模式的一些基本原则

  • 高内聚,低耦合
  • 单一职责
  • 开闭原则(对修改封闭、对扩展开放)

2.2 单例

所谓

单例也就是一个类只生成一个对象,无论你实例化多少对象,都是同一个对象

  • 应用场景:数据库操作类,文件操作类等,可以减少资源的占用

2.3 实现

  • 使用__new__
  class Singleton:
      __instance = None   # 保存实例的引用
      def __new__(cls, *args, **kwargs):
          if cls.instance is None:  # 如果实例没有实例化
              cls.__instance = object.__new__(cls,*args,**kwargs)  #实例化对象,将引用存到__instance
          return  cls.__instance #返回对象
  s1 = Singleton()
  s2 = Singleton()
  print(id(s1),id(s2))
  if s1 is s2:
      print('单例')

本文地址:https://blog.csdn.net/weixin_44799030/article/details/109915314

相关标签: python基础