类与面向对象

时间:2022-09-24 20:58:28

类(class):告诉Python创建新类型的东西

对象(object):两个意思,即最基本的东西,或某样东西的实例

实例(instance):这是让python在创建一个类时得到的东西

def:这是在类里定义函数的方法

self:在类的函数里,self指代被访问的对象或者实例的一个变量

继承(inheritance):指一个类可以继承另一个类的特性,和父子关系类似

组合(composition):指一个类可以将别的类作为它的部件构建起来,有点像车子与*的关系

属性(attribute):类的一个属性,它来自于组合,而且通常是一个变量

 

单继承

    子类有的就用子类的
没有的就用父类的
如果父类子类都想用,super(),父类名.方法名

多继承
   新式类 :继承object
       python2 要主动继承object才是新式类,默认是经典类
       遵循的是广度优先算法,C3算法
       有super()的,super遵循mro顺序的
       有mro()方法
   经典类 :不继承object
       多个类之间去寻找方法的时候遵循深度优先
       没有super方法也没有mro

当继承父类时,一经实例化,先执行父类__init__(self.object)当中的内容,若有打印或返回语句,则直接打印

 

抽象方法与接口

  我印象中的难点,学Java时简直不要太头大,直到最后都没能搞懂,只知道不可实例化

  python3中创建抽象方法需要导入 abc 模块

  

from abc import ABCMeta,abstractmethod  #导入 abc 模块中的 ABCMeta 和 abstractmethod 
class Animal(metaclass=ABCMeta):  
    def __init__(self,name,blood,ad):  
        self.name = name
        self.hp = blood
        self.ad = ad
    @abstractmethod  #装饰器 要求此装饰器下的一个方法必须在子类中出现/模板定型
    def bite(self,n):
        pass

先抽象,再继承  

继承:对象 -->类 -->基类     

抽象作用:基类 -继承-> 子类 -实例化-> 对象

 

面向对象的反射

class Student:
    def__init__(self,name):
        self.name=name
    def show_courses(self):
        pass
    def select_course(self):
        pass
wang=Student('填空题')
#反射 通过字符串属性名,得到这个字符串的名字对应的对象的属性值
name=input('>>>')
if hasattr(wang,name):  #判断name是否存在
  func_attr = getattr(wang,name)
  if callable(wu,name)  #判断是否可调用
    func_attr() #内置函数  
  else:
    print(func_attr) #仅打印 
setattr(Student,'username','2269265019')  #向Student类中添加了一个username属性,并为其赋值为'2269265019' (ps:无法真正添加方法,若强行实现效果,需在置入 类名 为参数)
delattr(Student,'username')  #我现在又不想要username属性了,将其删掉 (ps:无法删除方法)
 
 
 

 

   装饰器

dic={
    'pen':{'name':'????','price':'10'},
    'knife':{'name':'????','price':'20'}
}
class Shop:
    dir=[1,2,3]
    def __init__(self,dic):
        self.dic=dic
    def scan_goods(self):  #对象与方法的绑定
        for k in self.dic:
            print(self.dic[k]['name'],self.dic[k]['price'])
    @classmethod
    def delete_goods(self):  #类与方法的绑定
        print('>>>')
    @staticmethod
    def into(cls):  #静态方法 (ps:静态方法虽然可以全局调用,但并非全局属性)
        print(cls.dir)
we=Shop(dic)

 

封装

class A:
    c=0.8
class B(A):
    def __init__(self,name,price):
        self.__price=price  #双下划线__属性名可进行私有化,既无法于类外部显示,也无法于类外部使用 (ps:实际上是改名字了,更改为_B__price)
        self.name=name
    @property   #把一个方法伪装成一个属性
    def price(self):
        return self.__price*self.c
    @price.setter  #仅对被@property装饰的方法生效,可为其中的某一属性赋值
    def price(self,value):
        if type(value) is int or type(value) is float:
            self.__price=value
    @price.deleter
    def price(self):  #仅对被@property装饰的方法生效,用于删除其中的某一属性
        del self.__price
a=B('苹果',5)
a.price=8
# del a.price
print(a.price)
print(a.c)

 

isinstance 与 issubclass 方法

  isinstance(对象名,类名,cls)

    isinstance用来检测一个对象是否为某个类的实例化

    判断血缘关系

  issubclass(cls/子类,cls/父类)

    issubclass用来判断一个类是否为另一个类的子类

class A:pass
class B(A):pass
a=B()  #实例化B
print(isinstance(a, A))  #判断对象a是否为类A的实例化,与type不同,isinstance承认继承关系
print(issubclass(B,A))  #判断类B是否为类A的子类