类(A)

面向对象编程

  • 除了之前的字符串,数字,列表,元组和字典等内建对象类型,Python还支持创建自己的对象。
  • 作为一门面向对象编程的语言,把面对对象编程的过程叫做面对对象编程(oop : Object Oriented Programming)

类,就是用来描述具有相同属性和方法的对象的集合;类定义了集合中每个对象共有的属性和方法,对象是类的实例



类的定义与使用

class MyClass():                # class ClassName(object):
    i = 123                     # <statement-1>
    def f(self):                # .
        return 'hello world'    # <statement-N>
a = MyClass()                   # 类的实例化
print(a.i)                      # obj.name       类属性(变量)的引用
print(a.f())                    # obj.method()   类方法的引用

class关键字 + 类的名字 + (object)括号内可不写 +

类包含属性(i)与方法(f)。
在类中定义方法的形式核函数差不多,但不称为函数。方法的调用需要绑定在特定对象上,而函数不需要
在类中定义方法时,第一个参数必须是 self !



类的构造法 & 访问权限

构造法

class MyClass():
    i = 123
    def __init__(self,name):     # 初始化方法(构造法):所有实例化对象都必须满足此格式。即:除自身(self)外,还应带有一个参数(name)
        self.name = name         # 通过 obj.name 的方式引用类的name属性 
    def f(self):                 # 通过 obj.method() 的方式引用类的方法
        return 'hello,' + self.name
a = MyClass('p')                 # 所有的实例对象都必须满足此类格式,即括号内还有一个对应name的参数

print(a.f()) # hello,p
  • __ init__是类中的一个特殊方法,在对象实例化时自动调用;
  • __ init__的意思是初始化(initialization),若在定义类时,不显示的定义一个构造法,则程序会默认调用一个无参数的 __ init__()方法;
  • 一个类中可以定义多个构造法,但实例化只会调用最后定义个构造法,建议一个类只定义一个构造函数。

访问权限

  1. 在类中定义的非构造方法可以调用类中构造法的实例变量属性,即self.实例变量名(self.name ; self.score)通过此方法可以在类的外部轻易修改内部属性;
class Student(object):
    def __init__(self,name,score):
        self.name = name
        self.score = score
    def info(self):
        print(f'学生:{self.name};分数:{self.score}')

stu_1 = Student('David','95')
stu_1.info()
stu_1.score = '100'
stu_1.info()
学生:David;分数:95
学生:David;分数:100

  1. 若要让内部属性不被外部访问,可在属性名称加两个下划线(__name, __slef),实例的变量(属性)如果以 __开头,就会变成私有变量(private),外部无法直接访问
class Student(object):
    def __init__(self,name,score):
        self.__name = name    # 构造类Student 的私有变量 name
        self.__score = score  # 构造类Student 的私有变量 score
    def info(self):           # 定义类Student 的info()方法,可以查询实例的名字,对应分数
        print(f'学生:{self.__name};分数:{self.__score}')
        
stu_1 = Student('David','95')# stu_1作为类Student的一个实例
stu_1.info()                 # 通过类内部的info()方法间接访问了 name 和 score
stu_1.__score                # 直接访问类Student的私有属性score,报错

结果如下

学生:David;分数:95
Traceback (most recent call last):
  File "C:/Users/Administrator/PycharmProjects/untitled/venv/文本练习.py", line 148, in <module>
    stu_1.__score
AttributeError: 'Student' object has no attribute '__score'

  1. 若要访问或修改类中的私有属性(变量),可以通过定义方法来实现
class Student(object):
    def __init__(self,name,score):
        self.__name = name
        self.__score = score
    def info(self):
        print(f'学生:{self.__name};分数:{self.__score}')
    def setscore(self,score):   # 定义一个专门修改类Student私有属性(变量)的方法
        self.__score = score

stu_1 = Student('David','95')
sti_1.info()
stu_1.setscore('20')
stu_1.info()
学生:David;分数:95
学生:David;分数:20


类的继承

继承完全可以理解为类之间的类型和子类型的关系;继承的最大好处是子类将获得父类的全部非私有属性(变量),方法

 class DerivedClassName(BaseClassName): # 从BaseClassName类中定义一个DerivedClassName子类
      < statements-1 >
     .
     .
      < statements-N >
  • 在继承中,子类不会自动调用父类的构造法(__ init__()),需要在子类的构造方中单独调用
  • 在调用父类的方法时需要加上父类的类名前缀,并带上self参数
  • 在Python中,方法的调用机制是从子类到父类,如果在子类中找不到对应方法,便会在父类中查找


多态

  • 当子类和父类存在相同的方法时,在代码运行时总是执行子类的方法,称之为多态
  • 在继承关系中,如果一个实例的数据类型是某个子类,那他的数据类型也可以看做父类。
class Animal():            # 定义父类 Animal
    def __init__(self):    # 无参构造法
        pass
    def run(self):         # 定义父类的run()方法
        print('Animal is running')

class Dog(Animal):         # 定义子类Dog
    def __init__(self):   
        Animal.__init__(self)     # 调用父类的无参构造法,写法格式留意带上self参数
    def run(self):         # 定义子类的run()方法
        print('Dog is running')

class Cat(Animal):         # 定义子类Cat
    def __init__(self):
        Animal.__init__(self)
    def run(self):         # 定义子类的run()方法
        print('Cat is running')

doggy = Dog() # 将变量doggy实例化,它属于dog类,肯定也是Animal类
catty = Cat()
doggy.run()   # 当子类与父类存在相同的方法时,永远执行子类的方法,若子类没有对应方法,才会在父类中寻找
catty.run()
Dog is running
Cat is running

多态的意义在于
对于一个变量,我们只需要知道它是哪个父类类型,无需确切知道它从属哪个子类,就能放心调用父类中存在的方法,具体调用的方法作用于哪个子类对象,由运行时该对象的确切类型决定



多重继承

多重继承就是拥有多个父类

 class DerivedClassName(Base1,Base2,Base3...): 
      < statements-1 >
     .
     .
      < statements-N >

需要注意括号内父类的顺序,若父类中有相同的方法名,在子类使用时未指定,Python会从左至右搜索(含子类)

例:
现在有如下四种动物:Dog , Bat , Parrot , Ostrich
按照哺乳类 Mammal , 鸟类 Bird分类
按照会飞 Flyable , 会跑 Runnable 分类

class Animal():            # 定义父类 Animal
    pass

class Mammal(Animal):
    pass

class Bird(Animal):
    pass 

class Runnable(Animal):
    pass

class Flyable(Animal):
    pass

class Dog(Mammal,Runnable):  # 定义子类Dog
    pass

class bat(Mammal,Flyable):         
    pass
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值