一.什么是面向对象的程序设计以及为什么要有它
1.面向过程的编程思想:核心是过程二字,过程指的是解决问题的步骤,即先干什么,再干什么,后干什么,基于该思想编写程序就好比在设计一条流水线,是一种机械式的思维方式
优点:复杂的问题流程化,进而简单化
缺点:可扩展性差
2.面向对象的编程思想:核心是对象二字,对象是特征与技能的结合体,基于该思想编写的程序,就好比在创造一个世界,世界是由一个个对象组成的,在上帝眼里任何存在的事物都是对象,任何不存在的事物也
都可以造出来,是一种上帝式的思维方式
优点:可扩展性强
缺点:编程的复杂度要高于面向过程
二.类与对象
对象是特征与技能的结合体,而类则是一系列对象相同的特征与技能的结合体
强调:
1.对象是具体存在的事物,而类则是一个抽象的概念
2.站在不同的角度总结出的类与对象是不同的
在现实世界中:先有一个个具体存在的对象,然后随着人类文明的发展才总结出类的概念
在程序中:先定义类,然后调用类来产生对象
细说__init__方法!!!
#方式一:为对象初始化自己独有的特征
# class People:
# country="china"
# x=1
# def run(self):
# print('---------',self)
#
# #实例化出三个空对象
# obj1=People()
# obj2=People()
# obj3=People()
#
# #为对象定制自己独有的特征
# obj1.name="egon"
# obj1.age=18
# obj1.sex="male"
#
# obj2.name="petrus"
# obj2.age=28
# obj2.sex="male"
#
# obj3.name="alex"
# obj3.age=48
# obj3.sex="female"
#
# print(obj1.__dict__)
# print(obj2.__dict__)
# print(obj3.__dict__)
#方式二:为对象初始化自己独有的特征
# class People:
# country = "china"
# x = 1
#
# def run(self):
# print('---------', self)
#
#
# # 实例化出三个空对象
# obj1 = People()
# obj2 = People()
# obj3 = People()
#
# #为对象定制自己独有的特征
# def chu_shi_hua(obj,x,y,z):
# obj.name=x
# obj.age=y
# obj.sex=z
#
# chu_shi_hua(obj1,'egon',18,"male")
# chu_shi_hua(obj2,'petrus',28,"male")
# chu_shi_hua(obj3,'alex',48,"female")
#
# print(obj1.__dict__)
# print(obj2.__dict__)
# print(obj3.__dict__)
#方式三:为对象初始化自己独有的特征
# class People:
# country = "china"
# x = 1
#
# def chu_shi_hua(obj, x, y, z):
# obj.name=x
# obj.age=y
# obj.sex=z
#
# def run(self):
# print('---------', self)
#
# obj1=People()
# People.chu_shi_hua(obj1,"egon",18,"male")
#
# obj2=People()
# People.chu_shi_hua(obj2,"petrus",28,"male")
#
# obj3=People()
# People.chu_shi_hua(obj3,"alex",38,"female")
#
# print(obj1.__dict__)
# print(obj2.__dict__)
# print(obj3.__dict__)
# 方式四、为对象初始化自己独有的特征
#__init__方法
#强调:
# 1.该方法内可以有任意的python代码
# 2.一定不能有返回值
class People:
country='China'
x=1
def __init__(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
obj.name = x
obj.age = y
obj.sex = z
def run(self):
print('----->', self)
# obj1=People("egon",18,"male")
# obj2=People("petrus",28,"male")
# obj3=People("alex",48,"female")
#print(People.__module__)
#===========================================================
#python 为类内置的特殊属性
#类名.__name__ #类的名字(字符串)
#类名.__doc__ #类的文档字符串
#类名.__base__#类的第一个父类
#类名.__bases__#类所有父类构成的元组
#类名.__dict__ #类的字典属性
#类名.__module__#类定义所在的模块
#类名.__class__#实例对应的类(仅新式类中)
三.属性的查找
类有两种属性:数据属性和函数属性
1.类的数据属性是所有对象共享的
2.类的函数属性是绑定给对象用的
#类的数据属性是所有对象共享的,id都一样
class Student:
school="hust"
xxx=2222
count=0
def __init__(self,name,age,sex):
Student.count+=1
self.name=name
self.age=age
self.sex=sex
def choose_course(self):
print("%s choose the course" %self.name)
stu1=Student('李铁蛋',18,'male')
stu2=Student('赵钢弹',38,'female')
stu3=Student('刘银弹',28,'male')
#
print(id(stu1.school))
print(id(stu2.school))
print(id(stu3.school))
print(id(Student.school))
"""
2505052398624
2505052398624
2505052398624
2505052398624
"""
#类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样
#ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准
print(Student.choose_course)
print(stu1.choose_course)
print(stu2.choose_course)
print(stu3.choose_course)
"""
<function Student.choose_course at 0x000001D341E4A620>
<bound method Student.choose_course of <__main__.Student object at 0x000001D341E418D0>>
<bound method Student.choose_course of <__main__.Student object at 0x000001D341E41908>>
<bound method Student.choose_course of <__main__.Student object at 0x000001D341E41940>>
"""
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
四.绑定到对象的方法的特殊之处
class Student():
school="hust"
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def learn(self):
print("%s is learning" %self.name)
def eat(self):
print("%s is eating" %self.name)
def sleep(self):
print("%s is sleeping" %self.name)
s1=Student('李坦克','男',18)
s2=Student('王大炮','女',38)
s3=Student('牛榴弹','男',78)
Student.learn(s1) #李坦克 is learning
Student.learn(s2) #王大炮 is learning
Student.learn(s3) #牛榴弹 is learning
类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可以使用,但必须遵循函数的参数规则,有几个参数需要传几个参数
类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法
强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法__init__也是一样的道理)
注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定俗成地写出self。