python类和对象基础教程

本教程的
​​​​​​ 思维导图

1.类和对象

1.1什么是类?什么又是对象?

类和对象都是面向对象中的重要概念。面向对象是一种编程思想,即按照真实世界的思维方式构建软件系统。例如,在真实世界的校园里有学生和老师,学生有学号、姓名、所在班级等属性(数据),还有学习、提问、吃饭和走路等动作(方法)。如果我们要开发一个校园管理系统,那么在构建软件系统时,也会有学生和老师等“类”,张同学、李同学是学生类的个体,被称为“对象”,“对象”也被称为“实例”   类就是一个模板,具有相同属性和行为(方法)的对象的集合,对象是类的具象化,而类是对象的抽象化。类是模板,比如修房子的图纸,比如制作蛋挞的模型一样,有了这个模版,我们便可以创建真实的模的着看得见的实例,就是对象 万物皆对象!!!

通过小汽车类实例化不同的车(对象)

1.2定义类

Python中的数据类型都是类,我们可以自定义类,即创建一种新的数据类型。Python中类的定义语法格式如图所示

以上两种方式皆可,其中object是超类,也就是类的根,所有的类都继承自object类,可以不用写,我们便定义了一个小汽车的类,类名叫做Car  ,class是关键字  pass语句是用于维持程序的结构的完整性,当我们还不知道些什么的时候可以使用paa 这样程序也不会报错 当我们想好如何写的时候再写上相应的逻辑实现即可 ,使用pass便不会出现语法上的错误,起到占位的作用

1.3创建对象

类相当于一个模板,依据这样的模板来创建对象,就是类的实例化,所以对象也被称为“实例“,如下图所示,可以直观的理解类和对象的关系。

定义好啦Car类,然后我们创建了Car类的对象,通过类名加小括号创建了对象,然后赋值给变量car,此时系统会自动调用类的构造方法,用于初始化对象,比如创建对象的属性并进行赋值,该方法在创建对象后,系统自动执行类的构造方法,我们显示的写出来 但每个类都内置的有一个构造方法用于初始化对象 __init__(self,参数1,参数2,...),当我们创建的对象不需要的时候,便要对这个对象进行销毁,释放空间,在python中销毁对象由python垃圾回收器在后台释放对象,不需要我们手动的释放,当然我们想要手动释放也是可以的 析构方法 __del__(self),进行删除对象

2.类的成员

在类体中包含的类的成员如下图所示:

成员变量也被称为数据成员,保存了类或对象的数据。例如,学生的姓名和学号。

构造方法是一种特殊的函数,用于初始化类的成员变量。

成员方法是在类中定义的函数。

属性是对类进行封装而提供的特殊方法。

问:实例变量和实例方法与类变量和类方法有什么区别呢?

答:实例变量和实例方法属于对象,通过对象.变量名或者方法名进行使用,而类方法和类变量是通过类进行使用类名.名字,当然也可以通过对象.名字调用,因为类里面的公有东西对象都可以访问调用,python中类里面的对象默认是公有的,有些成员如果设置为私有的我们在类外便不能通过对象直接调用

2.1实例变量

实例变量就是对象个体特有的“数据”,例如狗狗的名称和年龄等等,我们来写一个Dog类,然后实例化狗类对象dog1,通过Dog类的构造方法为dog这个实例进行属性的添加并且初始化赋值,dog对象有名字,和年纪和性别这三个个属性,性别我们默认为雄性,如下所示:

__init__(self,参数列表)类是构造方法,是内置方法,当我们实例出一个对象的时候系统自动会执行,我们在创建对象dog的时候,执行构造方法并给其属性赋值,我们没有传递sex,默认为雄性,自己也可以指定性别 注意构造方法的第一个参数self,就是对象的引用,大白话就是执行构造方法的时候,把这个对象传进去了,self.name等价于dog.name可以这样理解,python中是把该对象和self进行了绑定,self就是dog,dog就是self,这样理解就好

2.2构造方法

类中的__init__()方法是一个非常特殊的方法,用来创建和初始化实例变量,这种方法就是“构造方法”。在定义__init__()方法时,它的第1个参数应该是self,之后的参数用来初始化实例变量。调用构造方法时不需要传入self参数,

代码示例:

#定义类
class Dog(object):
    #类体
    def __init__(self,name,age,sex="雄性"):
        self.name=name
        self.age=age
        self.sex=sex
dog=Dog("小花",2,sex="雌性")#实例化Car类的对象,并初始化属性
print("我叫{},我现在{}啦,我是{}滴".format(dog.name,dog.age,dog.sex))

2.3实例方法

实例方法与实例变量一样,都是某个实例(或对象)个体特有的方法,定义实例方法时,它的第1个参数也应该是self,这会将当前实例与该方法绑定起来,这也说明该方法属于实例。在调用方法时不需要传入self,类似于构造方法,举个例子,我们来理解一下,比如说我创建了dog对象,他现在有了名字年纪还有性别,我再给她写个跑的方法,和说的方法,让狗狗跑起来,会汪汪叫,这便是实例方法,具体如下所示:

#定义类
class Dog(object):
    #类体
    def __init__(self,name,age,sex="雄性"):
        self.name=name
        self.age=age
        self.sex=sex
    #定义实例方法,跑起来让狗狗
    def run(self):
        print("{}跑起来了".format(self.name))
    #定义实例方法,说 让狗狗叫起来
    def speak(self):
        print("{}在汪汪叫".format(self.name))
dog1=Dog("小花",2,sex="雌性")#实例化Car类的对象,并初始化属性
dog2=Dog("小黑",3)
print("我叫{},我现在{}啦,我是{}滴".format(dog.name,dog.age,dog.sex))
dog1.run()
dog1.speak()
dog2.run()
dog2.speak()

2.4类变量

类变量是属于类的变量,不属于单个对象,例如,有一个Account(银行账户)类,它有三个成员变量:amount(账户金额)、interest_rate (利率)和owner(账户名)。amount和owner对于每一个账户都是不同的,而interest_rate对于所有账户都是相同的。amount和owners是实例变量,interest_rate是所有账户实例共享的变量,它属于类,被称为“类变量”类变量的示例代码如下:

#定义类Account
class Account:
    interest_rate=0.987#类变量利率
    def __init__(self,owner,amount):
        self.owner=owner#创建并初始化实例变量owner
        self.amount=amount#创建并初始化实例变量amount
account=Account("rose",50000000)
print("账户名:{}".format(account.owner))
print("账户余额:{}".format(account.amount))
print("利率:{}".format(Account.interest_rate))

        

2.5类方法

类方法与类变量类似,属于类,不属于个体实例。在定义类方法时,它的第1个参数不是self,而是类本身,如下所示:

#定义类Account
class Account:
    interest_rate=0.987#类变量利率
    def __init__(self,owner,amount):
        self.owner=owner#创建并初始化实例变量owner
        self.amount=amount#创建并初始化实例变量amount
    #定义类方法
    @classmethod
    def interest_by(cls,mat):#cls表示自身类也就是Account
        return cls.interest_rate*mat#cls也可以换成Account 
#account=Account("rose",50000000)
# print("账户名:{}".format(account.owner))
# print("账户余额:{}".format(account.amount))
# print("利率:{}".format(Account.interest_rate))
print(Account.interest_by(50000))
ac1=Account("jike",80000000)
print(ac1.interest_by(50000))

        

3.封装性

封装性是面向对象重要的基本特性之一。封装隐藏了对象的内部细节,只保留有限的对外接口,外部调用者不用关心对象的内部细节,使得操作对象变得简单。例如,一台计算机内部极其复杂,有主板、CPU、硬盘和内存等,而一般人不需要了解它的内部细节。计算机制造商用机箱把计算机封装起来,对外提供了一些接口,如鼠标、键盘和显示器等,使用计算机就变得非常简单。

3.1私有变量

为了防止外部调用者随意存取类的内部数据(成员变量),内部数据(成员变量)会被封装为“私有变量”。外部调用者只能通过方法调用私有变量。在默认情况下,Python中的变量是公有的,可以在类的外部访问它们。如果想让它们成为私有变量,则在变量前加上双下画线(__)即可

示例代码如下:

#定义类Account
class Account:
    __interest_rate=0.987#类变量利率
    def __init__(self,owner,amount):
        self.owner=owner#创建并初始化实例变量owner
        self.__amount=amount#创建并初始化实例私有变量amount
    def desc(self):
        print("账户名:{} 金额:{} 利率:{}".format(self.owner,self.__amount,self.__interest_rate))
account=Account("daday",8000000)
account.desc()
    

注意,在类的外部不可以访问私有变量,如下所示:

如果我们要在类外面访问类的私有成员,我们可以在私有成员前面加_类名即可,如下所示:

#定义类Account
class Account:
    __interest_rate=0.987#类变量利率
    def __init__(self,owner,amount):
        self.owner=owner#创建并初始化实例变量owner
        self.__amount=amount#创建并初始化实例私有变量amount
    def desc(self):
        print("账户名:{} 金额:{} 利率:{}".format(self.owner,self.__amount,self.__interest_rate))
account=Account("daday",8000000)
account.desc()
print("账户金额{}".format(account._Account__amount))
print("利率为{}".format(Account._Account__interest_rate))
    

3.2私有方法

私有方法与私有变量的封装是类似的,在方法前加上双下画线(__)就是私有方法了。示例代码如下:

#定义类Account
class Account:
    __interest_rate=0.987#类变量利率
    def __init__(self,owner,amount):
        self.owner=owner#创建并初始化实例变量owner
        self.__amount=amount#创建并初始化实例私有变量amount
    #定义普通方法
    def desc(self):
        print(self.__get_info())
    #定义私有方法
    def __get_info(self):
        return "账户为:{},金额有:{},利率是:{}".format(self.owner,self.__amount,self.__interest_rate)
account=Account("daday",8000000)
account.desc()
#account.__get_info()
    

注意在类外调用__get_info()方法的时候,会报错,如果想要调用的话,需要在方法名前面加__类名,两条下划线加类名即可,如下所示:

#定义类Account
class Account:
    __interest_rate=0.987#类变量利率
    def __init__(self,owner,amount):
        self.owner=owner#创建并初始化实例变量owner
        self.__amount=amount#创建并初始化实例私有变量amount
    #定义普通方法
    def desc(self):
        print(self.__get_info())
    #定义私有方法
    def __get_info(self):
        return "账户为:{},金额有:{},利率是:{}".format(self.owner,self.__amount,self.__interest_rate)
account=Account("daday",8000000)
account.desc()
print(account._Account__get_info())
    

3.3使用属性

为了实现对象的封装,在一个类中不应该有公有的成员变量,这些成员变量应该被设计为私有的,然后通过公有的set (赋值)和get(取值)方法访问。使用set和get方法进行封装,示例代码如下

class Dog:
    def __init__(self,name,age,sex="雄性"):
        self.name=name
        self.__age=age#给私有属性age赋值
        self.sex=sex
    #实例方法
    def run(self):
        print("{}在跑",format(self.name))
    #给age设置get方法,返回age
    def get_age(self):
        return self.__age
    #修改私有属性age的set方法
    def set_age(self,new_age):
        self.__age=new_age
#实例化狗狗对象,并初始化赋值给狗狗对象
dog=Dog("小黄",2,sex="雌性")
print("{}是的年纪为{}岁,是{}滴".format(dog.name,dog.get_age(),dog.sex))
dog.set_age(3)#修改狗狗的年纪
print("修改后的{}的年纪为{}岁".format(dog.name,dog.get_age()))
        

上述示例中,当外部调用者通过两个公有方法访问被封装的私有成员的时候,会比较麻烦,我们可以修改一下,类属性(property)便是解决这种的,我们可以在类中定义属性,属性替代get()和set()方法,这样调用就会比较简单修改上述代码,如下所示:

class Dog:
    def __init__(self,name,age,sex="雄性"):
        self.name=name
        self.age=age#给私有属性age赋值
        self.sex=sex
    #实例方法
    def run(self):
        print("{}在跑",format(self.name))
    @property
    def age(self):#替代get_age(self)
        return self.__age
    @age.setter
    def age(self,new_age):#替代set_age(self,new_age)
        self.__age=new_age
#实例化狗狗对象,并初始化赋值给狗狗对象
dog=Dog("小黄",2,sex="雌性")
print("{}是的年纪为{}岁,是{}滴".format(dog.name,dog.age,dog.sex))#通过属性取值访问形式为对象.属性
dog.age=3#修改狗狗的年纪,替代dog.set_age(3)
print("修改后的{}的年纪为{}岁".format(dog.name,dog.age))

属性的本质就是方法,在方法前面加一个装饰器,使得方法变为了属性 属性使用起来类似于公有变量,可以在赋值符号(=)左边或者右边,在左边为赋值,在右边为取值

4.继承性

继承性也是面向对象重要的基本特性之一,在现实世界中继承关系无处不在。例如猫与动物之间的关系:猫是一种特殊动物,具有动物的全部特征和行为,即数据和操作。在面向对象中动物是一般类,被称为“父类”;猫是特殊类,被称为“子类”。特殊类拥有一般类的全部数据和操作,可称之为子类继承父类

4.1python中的继承

在Python中声明子类继承父类,语法很简单,定义类时在类的后面使用一对小括号指定它的父类就可以了。下面是动物类继承图

代码如下:

class Animal:
    def __init__(self,name):
        self.name=name
    def print_info(self):
        print("动物的名字为{}".format(self.name))
    def run(self):
        print("动物在跑.....")
class Cat(Animal):#定义子类Cat继承了父类Animal的属性和方法
    def __init__(self,name,age):
        super().__init__(name)#调用父类的构造方法为其赋值
        self.age=age
#实例化子类对象
cat=Cat("小黄",2)
cat.run()#调用父类的方法
cat.print_info()#调用父类的方法
        

子类继承父类的时候,只有父类的公有的变量和方法会被继承给子类,注意在子类的构造方法中调用父类的构造方法的时候,初始化子类实例的成员的时候同时也初始化父类的实例变量,先是初始化父类的,在初始化子类的!!

4.2多继承及方法重写

在Python中,当子类继承多个父类时,如果在多个父类中有相同的成员方法或成员变量,则子类优先继承左边父类中的成员方法或成员变量,从左到右继承级别从高到低,如下:

代码如下所示:

class Teacher:
    def __init__(self,name,age,course):
        self.name=name
        self.age=age
        self.course=course
    def print_info(self):
        print(f"老师的名字是:{self.name} 年纪为:{self.age}岁 教的课程为:{self.course}")
    def shangke(self):
        print(f"{self.name}正在上{self.course}课")
class Student:
    def __init__(self,name,age,gread):
        self.name=name
        self.age=age
        self.gread=gread
        
    def print_info(self):
        print(f"学生的名字是{self.name},年纪为:{self.age}岁,读{self.gread}级")
    def shangke(self):
        print(f"{self.name}正在上课")
class ZhuJiao(Teacher,Student):
    def __init__(self,name,age,course,gread,jk):#jk为讲课 gread为年级
        super().__init__(name,age,course)#调用teacher类的构造方法实例化属性
        self.gread=gread
        self.jk=jk
    def print_info(self):#重写了父类的方法
        print(f"{self.name}今年{self.age}岁了,读{self.gread}在给同学讲{self.jk}课:")
zj=ZhuJiao("小李",20,"数学微积分","大学","数学课程习题")
zj.print_info()
zj.shangke()
 

分析:助教类继承了老师类和学生类分别,在定义助教类的时候添加了自己的讲课属性,继承了来自老师类的和学生类的所有方法和属性,同时重写了父类的print_info()方法,两个父类都有shangke()的方法,助教对象调用shangke()方法的时候,是优先调用左边的父类,也就是调用老师类的shangke()方法

5.多态性

多态性也是面向对象重要的基本特性之一。“多态”指对象可以表现出多种形态。例如,猫、狗、鸭子都属于动物,它们有“叫”和“动”等行为,但是叫的方式不同 比如,小狗是汪汪叫,小猫是喵喵叫,小鸭子是嘎嘎叫。

5.1继承与多态

在多个子类继承父类,并重写父类方法后,这些子类所创建的对象之间就是多态的。这些对象采用不同的方式实现父类方法。示例代码如下:

class Animal:
    def speak(self):
        print("动物在叫,但不知道是哪种动物再叫...")
class Dog(Animal):
    def speak(self):
        print("小狗狗在汪汪叫.....")
class Cat(Animal):
    def speak(self):
        print("小喵咪在喵喵叫.....")
class Duck(Animal):
    def speak(self):
        print("小鸭子在嘎嘎叫.....")
dog=Dog()
cat=Cat()
duck=Duck()
dog.speak()
cat.speak()
duck.speak()

5.2鸭子类型测试与多态

Python的多态性更加灵活,支持鸭子类型测试。鸭子类型测试指:若看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子

由于支持鸭子类型测试,所以Python解释器不检查发生多态的对象是否继承了同一个父类,只要它们有相同的行为(方法),它们之间就是多态的。

例如,我们设计一个函数start()它接收具有“叫”speak()方法的对象,代码如下:

class Animal:
    def speak(self):
        print("动物在叫,但不知道是哪种动物再叫...")
class Dog(Animal):
    def speak(self):
        print("小狗狗在汪汪叫.....")
class Cat(Animal):
    def speak(self):
        print("小喵咪在喵喵叫.....")
class Duck(Animal):
    def speak(self):
        print("小鸭子在嘎嘎叫.....")
class Car:
    def speak(self):
        print("小车嘟嘟嘟叫.......")
def star(obj):#定义一个函数用来接收对象具有speak()方法
    obj.speak()
    
dog=Dog()
cat=Cat()
duck=Duck()
car=Car()
star(dog)
star(cat)
star(duck)
star(car)

6.练一练

1 在下列选项中,哪些是类的成员。()

A.成员变量

B.成员方法

C.属性

D.实例变量

2 判断对错:(请在括号内打√或×,√表示正确,×表示错误)

1)在Python中,类具有面向对象的基本特性,即封装性、继承性和多态性。()

2)__init__()方法用来创建和初始化实例变量,这种方法就是“构造方法”。()

3)类方法不需要与实例绑定,需要与类绑定,在定义时它的第1个参数不是self。()

4)实例方法是在类中定义的,它的第1个参数也应该是self,这个过程是将当前实例与该方法绑定起来。()

5)公有成员变量就是在变量前加上两个下画线(__)。()

6)属性是为了替代get()方法和set()方法。()

7)子类继承父类时继承父类中的所有成员变量和方法。()

8)Python中的继承是单继承。()

3 请介绍什么是“鸭子类型”?

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值