python基础知识(五)
(六)类与对象
类:某一类具有共同属性和特性的事物或者说是一个抽象的描述,比如说大佬类,你就是大佬类里面具体的一个实例。类一般包含属性和方法
(1)类的语法:
class 类名:
类属性
类方法/类函数
类属性:放在类里面的变量值,相当于我们自己在类里面定义的属性
类方法/类函数:写在类里面的函数,类里面的方法都必须带self这个参数,self代表实例本身,我们可以理解为这是一个实例方法的标志。
例如,写一个男朋友的类:
1 class BoyFriend: 2 # 类属性 3 height = 175 4 weight = 130 5 money = "500万" 6 7 # 类函数 8 def cooking(self): 9 print ("男朋友要会做饭") 10 11 def earn(self): 12 print ("男朋友的月薪是3万") 13 14 15 bf = BoyFriend () # 实例 16 print (bf.money)
打印出来的结果是:500万
注:类属性和类方法不是一定要同时写在类里面,可以只写类属性,也可以只写类方法。
(2)类名的规范
由数字字母下划线组成,不能以数字开头,首字母大写,驼峰命名(例:TestCase);
(3)实例/对象:具体的一个例子
a、创建实例/对象:类名()
实例具有类里面所有的属性和方法的使用权,实例可以调用类里面的任意属性和任意方法/函数;
b、调用属性
实例.属性名
c、调用方法/函数名
实例.方法名()
实例.函数名()
例如:
1 class Teacher: 2 name = "xiaozhu" 3 age = "20" 4 5 def coding(self): # 实例方法 6 print (self.name + "会敲代码") 7 8 def cooking(self): # 实例方法 9 print (self.name + "会做饭") 10 11 @classmethod # 类方法 12 def swimming(cls): 13 print ("会游泳") 14 15 @staticmethod 16 def sing(): # 普通函数 17 print ("会唱歌") 18 19 20 t = Teacher () # 实例 21 t.coding ()
打印出来的结果是:xiaozhu会敲代码
但是这里就存在一个问题,所有的人都叫xiaozhu,年龄都是20岁,在接下来会讲到一个初始化函数,可以解决这个问题~👇
d、类里面的方法
类里面的方法分为三种:
实例方法:意味着这个方法只能实例来调用,一般不传动态参数和关键字参数,必须要创建实例来进行调用 类名()
隐式传递:t=Teacher()
显示传递(不建议使用):Teacher.coding(t)
类方法:@classmethod 要传一个cls参数
类方法调用:Teacher.swimming() t.swimming()
静态方法:@staticmethod 不需要传参数
静态方法调用: Teacher.swimming() t.sing()
注:实例方法(self)、类方法(cls)、静态方法(普通方法),实例和类名都可以直接调用;
类方法和静态方法可以直接类名.方法名来进行调用,实例方法必须要创建实例才可以进行调用 类名()。
不同点:静态方法和类方法不可以调用类里面的属性值,如果要参数的话就需要自己传参数进去;
e、什么时候去定义为静态方法和类方法?(运用场景)
当你的某个函数与其他的类函数、类属性没有任何关系,就可以定义为静态方法和类方法,这样做的目的仅仅是为了方便调用。
(4)初始化函数
语法:def __init__(self,参数1,参数2,参数3.....参数n):
用法:def __init__(self,a,b):
self.a=a
self.b=b
注:
a、初始化里面做的是初始化操作,可以带参数也可以不带参数;
b、跟普通函数一样,可以带默认参数;
c、初始化函数里面可以有赋值好了的属性值;
d、每次创造一个实例,需要传递跟初始化函数参数个数一致的值;
e、每个实例都自动调用初始化函数,需要传递对应的参数;
f、初始化参数的写法要注意,怎么把参数赋值给self.参数名,参数名字不一定要一致,但是赋值要正确;
g、初始化函数没有返回值。
例如:
1 class Student: 2 def __init__(self, name, age): # 实例方法 3 self.name = name 4 self.age = age 5 6 def coding(self,lines,language='python'): # 实例方法 7 print (self.name + "会敲{0}代码,敲了{1}行代码".format(language,lines)) 8 9 def cooking(self,*args): # 实例方法 10 for item in args: 11 print (self.name + "会做{0}".format(item)) 12 13 @classmethod # 类方法 14 def swimming(cls): 15 print ("会游泳") 16 17 @staticmethod # 类方法 18 def sing(): 19 print ("会唱歌") 20 21 22 t1 = Student ("xiaozhu", "20") 23 t1.coding(10000) 24 t1.cooking('蛋炒饭','辣椒炒肉','麻辣小龙虾')
打印出来的结果是:xiaozhu会敲python代码,敲了10000行代码
xiaozhu会做蛋炒饭
xiaozhu会做辣椒炒肉
xiaozhu会做麻辣小龙虾
初始化函数的使用场景:想用的时候就用;如果某个属性值是多个函数共用的,就可以用初始化函数。
(5)继承
a、继承是我们类里面学习的一个重要的概念
继承的定义:
被继承的类---->父类
获得继承的类---->子类
子类继承父类所有函数及其属性的操作就称之为类的继承
b、继承的语法
class 子类名称(父类名称):
这里可以写自己需要的属性或者函数
注:
1、继承的类是否要用到初始化函数,要看有没有从父类里面继承了初始化函数;
2、父类有的,子类继承以后可以直接拿过来用;
3、子类里面的函数与父类里面的函数名重复的时候,子类的实例会优先调用子类的函数,如果子类没有的话再调用父类的。
c、类的重写和拓展
重写:子类对父类里面的部分属性或者是函数,想重新定义进行修改,就可以进行重写;
重写的特点:
1、子类的属性名称可以与父类一致,创建新的子类对应的实例,会调用最新改写的子类属性;
2、子类的函数名称可以与父类一致,创建新的子类对应的实例,会调用最新改写的子类函数。
拓展:新增父类里面没有的属性和类方法,只属于子类专有的方法和属性。
d、多继承
python支持多继承,可以同时继承多个类(了解),多继承如果子类继承了两个类,那么子类就会具有这两个父类的属性和方法,如果两个父类具有同名的方法时,子类调用函数就会采取就近原则,初始化函数也包括在内;
例如:
1 class RobotOne: 2 def __init__(self, year, name): 3 self.year = year 4 self.name = name 5 6 def walking_on_ground(self): 7 print (self.name + "只能在平地上行走") 8 9 def robot_info(self): 10 print ("{0}年生产的机器人{1}是中国研发出来的".format (self.year, self.name)) 11 12 13 class RobotTwo (): 14 def __init__(self,name): 15 self.name=name 16 17 def walking_on_ground(self): 18 print (self.name + "在平地上平稳的行走") 19 20 def walking_avoid_block(self): # 拓展 21 print (self.name + "可以避开障碍物") 22 23 24 # 25 # t = RobotTwo ("1888", "xiaozhu") 26 # t.robot_info () 27 # t.walking_on_ground () 28 class RobotThree (RobotOne, RobotTwo): 29 def jump(self): 30 print (self.name + "可以跳") 31 32 33 r = RobotThree ("1999", 'xiaozhu') 34 r.jump() 35 r.walking_on_ground()
打印出来的结果是:
xiaozhu可以跳
xiaozhu只能在平地上行走
e、超继承
如果你重写了父类里面的一个方法,又想调用父类里面的一些方法,就可以用超继承,我们到时候在单元测试的时候就会用到这个操作,不用去重写复制代码,这样就可以做到更多的继承(了解会用)
例如:
1 class RobotOne: 2 def __init__(self, year, name): 3 self.year = year 4 self.name = name 5 6 def walking_on_ground(self): 7 print (self.name + "只能在平地上行走") 8 9 def robot_info(self): 10 print ("{0}年生产的机器人{1}是中国研发出来的".format (self.year, self.name)) 11 12 13 class RobotTwo (RobotOne): # 继承 14 15 def walking_on_ground(self): 16 print (self.name + "在平地上平稳的行走") 17 18 def walking_avoid_block(self): # 拓展 19 # 在子类的函数里面调用父类的函数 20 self.robot_info () 21 print (self.name + "可以避开障碍物") 22 23 24 t = RobotTwo ("1888", "xiaozhu") 25 t.robot_info () 26 t.walking_on_ground ()
打印出来的结果是:
1888年生产的机器人xiaozhu是中国研发出来的
xiaozhu在平地上平稳的行走
超继承的例子🌰:
超继承的关键字super,超继承使用场景:想用父类的方法,但是又不想重新写的话就可以用超继承。
1 # 超继承 2 class MathMethod: 3 def __init__(self, a, b): 4 self.a = a 5 self.b = b 6 7 def add(self): 8 print ("我是父类的加法",self.a + self.b) 9 10 def sub(self): 11 return self.a - self.b 12 13 14 class MathMethod_1 (MathMethod): 15 16 def divide(self): # 拓展 17 return self.a / self.b 18 19 def add(self): # 重写 20 super(MathMethod_1,self).add() # 超继承 21 print ("我是子类的加法",self.a + self.b + 10) 22 23 MathMethod_1(4,3).add()
打印出来的结果是:
我是父类的加法 7
我是子类的加法 17
👉做点习题:
1 No.1 创建一个名为 User 的类: 2 1)其中包含属性 first_name 和 last_name,还有用户简介通常会存储的其他几个属性,均是自定义, 请放在初始化函数里面。 3 2)在类 User 中定义一个名为 describe_user()的方法,它打印用户信息摘要; 4 3)再定义一个名为 greet_user()的方法,它向用户发出个性化的问候; 5 请创建3个不同用户的实例,并对每个实例都调用上述两个方法 6 7 8 9 10 No.2 定义一个学生类。 11 1)有下面的类属性: 1 姓名 2 年龄 3 成绩(语文,数学,英语)[每课成绩的类型为整数] ,均放在初始化函数里面。 12 2)类方法: 13 a)获取学生的姓名:get_name() 返回类型:str 14 b)获取学生的年龄:get_age() 返回类型:int 15 c) 返回3门科目中最高的分数 get_course() 返回类型:int 16 写好类以后,可以用以下的数据来测试下: 17 zm = Student('zhangming',20,[77,88,99])
以上的题目可以自行练习,如果需要参考答案私我呀~(如果阁下足够厉害,自动忽略这句话)