类与对象知识整理
1.类和对象有什么关系?
类和对象的关系就如同模具和用这个模具制作出的物品之间的关系。一个类为它的全部对象给出了一个统一的定义,而他的每个对象则是符合这种定义的一个实体,因此类和对象的关系就是抽象和具体的关系。
2.如果我们定义了一个狗类,那你能想象出由“狗”类实例化的对象有哪些?
柴犬,阿拉斯加,柯基,哈士奇。。。
3.类的创建与实例
自动检测
class Dog():
def __init__(self, name):#给了dog类一个参数name,并初始化
self.name = name
keji = Dog('旺财')#Dog类的实例,实例对象是keji
print(keji.name)
输出:旺财
注意:函数def后面一定是跟着一个空格
4.给类方法传参
class 类名():
def 类函数(self,参数):#这里传了一个参数,实例时需要给一个值
print(参数)
实例1 = 类名()#实例
实例1.类函数(值)#调用类方法,并给对应参数一个值,括号里面等同于(参数 = 值)
5.类中的函数跟变量有什么特殊含义?
类中的函数叫方法,类中的变量如下例子所示:
name = '张三' #类变量(即类属性)
def __init__(self):
self.age = 18 #成员变量
def study(self):
self.difficulty = '中'
subject= '数学' #函数内部的局部变量
print(Student.name)
student1 = Student()
print(student1.name)
print(student1.age)
student1.study()#成员变量由于在方法中创建,所以必须先调用方法
print(student1.difficulty)
#print(student1.subject) #若打印出来,将会报该类没有subject属性
输出:
张三
张三
18
中
运行上面代码,我们可以知道:
name是类变量,它可以由类名Student直接调用,也可以由对象student1来调用
age是成员变量,因为它是在构造函数(init)内以self.开头来定义的。可以由类的对象来调用,这里可以看出成员变量一定是以self.的形式给出的,因为self的含义就是代表实例对象;
difficulty不是成员变量,虽是以self.给出,但并没有在构造函数(init)中进行初始化。
subject不是成员变量,它只是study函数中的局部变量
6.self是什么?
首先明确的是self只有在类的方法中才会有,独立的函数或方法是不必带有self的。self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。
self名称不是必须的,在python中self不是关键词,你可以定义成a或b或其它名字都可以,但是约定成俗(减少理解难度),不要搞另类,大家会不明白的。
下例中将self改为myname一样没有错误:
def __init__(myName,name):
myName.name=name
def sayHello(myName):
print('My name is:',myName.name)
p=Person('bill')
print(p.name)
输出:bill
7.类的继承
-
类的继承很大程度也是为了避免重复性劳动。比如说当我们要写一个新的类,如果新的类有许多代码都和旧类相同,又有一部分不同的时候,就可以用“继承”的方式避免重复写代码;
-
子类创建的实例,同时属于父类;
-
父类创建的实例,不属于子类;
-
所有实例,都属于根类object;(即class Student(object) object平时都是省略)
子类与父类
- 子类除了可以定制新的类方法,还能直接覆盖父类的方法;
2.【单继承】:一个子类从一个父类中继承类方法;
class 子类(父类)
3.【多重继承】:一个子类从多个父类中继承类方法,具有就近原则(在子类调用属性和方法时,优先考虑靠近子类的父类)
class 子类(父类1,父类2...)
- 【多层继承】:子类的创建,可以调用所有层级的父类的属性和方法
class B(A):
class C(B):
案例1:类的定制(继承父类后新增类方法)
eye = 'black'
def eat(self):
print('吃饭,选择用筷子。')
class Cantonese(Chinese): # 类的继承
native_place = 'guangdong' # 类的定制(即新增一个类变量)
def dialect(self): # 类的定制(即新增一个函数)
print('我们会讲广东话。')
yewen = Cantonese()#实例化子类
print(yewen.eye) # 父类的属性能用
print(yewen.native_place) # 子类的定制属性也能用
yewen.eat() # 父类的方法能用
yewen.dialect() # 子类的定制方法也能用
案例2 :类的重写
def __init__(self):
self.skinColor = 'yellow'#父类成员变量skinColor
self.language = '普通话'#父类成员变量language
class Cantonese(Chinese): # 类的继承
def __init__(self):#重写初始化函数
#Chinese.__init__(self) #继续引用父类的初始化方法
self.language = '广东话'#修改成员变量language
person1 = Cantonese()#子类实例化
print(person1.language)
#print(person1.skinColor)
#由于直接重写父类初始化方法,所以成员变量只有language,
#想要继续引用skinColor变量,初始化必须在写上父类初始化方法,
#可把上方代码第8和13行注释的#号删了,运行测试一下
输出:广东话
注释#号删了运行后:输入 广东话
yellow
8._ init_初始化的作用,和str的用处
加上下划线的函数名都是有特殊含义的,每一个都一样
init的作用是,只要你建立一个实例,这个函数里面的代码就自动运行一遍,不需要专门调用这个函数
str的作用,如果这个函数里有return语句,自动将返回值打印出来,不用专门写print
8。初始化函数
你把类理解成一种复杂的变量,这个变量到底在计算机中占多大?于是你要初始化所有类中用到的变量,告诉计算机这个类里面都有哪些变量,类型都是什么(这样计算机才知道开多大内存)已经里面放什么(赋值)
类和函数的区别,为什么要有类,就像比如说你有衣服,这个衣服你就可以理解为函数,但是吧,你的衣服可能要分冬天穿的和夏天穿的,这样你就要整理箱,把东西都装起来。冬天穿的放到一起,然后夏天穿的放到一起,为什么要这样呢?就是因为方便使用。这里的整理箱也把它理解为类
习题:
一、按照一下要求定义一个游乐园门票类,并尝试计算2个成人+1个小孩子平日票价
1.平日票价100元
2.周末票价为平日票价120%
3.儿童半价
参考答案:
class Ticket:
pice = 100 #类属性
weekend = pice*0.2+pice #类属性
def compute(self,adultNum,childNum,isweekend):#类方法,计算金额(在调用是必须给三个参数值)
if(isweekend=='no'):
total = adultNum*self.pice+childNum*(self.pice/2)#类属性可以用self.变量名调用
print("应该支付总金额:",str(total))
elif(isweekend=='yes'):
total = adultNum*self.weekend+childNum*(self.weekend/2)
print("应该支付总金额:",str(total))
else:#处理输入其他值的情况
print("输入有误")
print("welcome to 迪斯尼 ")
adult = int(input("请输入成年人数量"))
child = int(input("请输入小孩数量"))
isweekend = input("是否是周末?yes/no")
t = Ticket()
t.compute(adult,child,isweekend)#给参数赋值,
#三个变量的值依次对应三个参数,顺序不能乱!
解析:
首先,先建一个Ticket类,票价由于在其他类函数中需要用到,所以可以设置成类属性
其次,考虑到要统计票价,所以需要写个类方法来处理,由于考虑到让系统更智能,因而将成人数量,小孩数量以及是否为周末等信息通过类外部获取(如不需要,可直接将这三个数定义为局部变量,赋固定值)所以,需要3个参数。
函数内部要先判断是不是周末,如果不是周末,那么票价就是price,如果是周末,那么票价就是weekend
最终,将成人数量,小孩数量以及是否为周末的值设置为,由用户自己输入,并将值传到实例后的compute方法里面。