一 概念
类和对象是面向对象编程的两个核心概念
1.类
-
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用
– 特征被称为属性
他是什么样的
– 行为被称为方法
他可以做什么
-
类就是相当于建造房子时的施工图纸(blueprint),是一个模板,是负责创建**房子(对象)**的
2.对象
- 对象是由类创造出来的一个具体存在,可以直接使用
- 由哪一个类创建出来的对象,就拥有在哪一个类中定义的(属性和方法)
- 对象相当于用施工图纸建造的房子
在程序开发中,应该先有类,再有对象
3.类与对象的关系
- 类是模板,对象是根据类这个模板创建出来的
- 先有类,再有对象
- 类只有一个,而对象可以有很多个
– 不同的对象之间属性可能会各不相同 - 类 中定义了什么属性和方法,对象中就有什么属性和方法,不可能多,也不可能少
二 类的设计
1.类的设计要素
在程序开发中,要设计一个类,通常需要满足以下三个要素:
- 类名
– 满足大驼峰命名法 - 属性
– 这类事物具有什么样的特征 - 方法
– 这类事物具有什么样的行为
2.大驼峰命名法
- 每一个单词的首字母大写
- 单词与单词之间没有下划线
3.确定类名
名词提炼法分析整个业务流程,出现的名词,通常就是找到的类
4.确定属性和方法
- 对 对象的特征描述,通常可以定义成属性
- 对象具有的行为(动词),通常可以定义成方法
class Person:
"""
define a person class
"""
# 实例方法(构造方法)
def __init__(self,name,age,height,weight): # self表示实例方法,实例本身
self.name = name # 实例属性
self.age = age
self.height = height
self.weight = weight
print("姓名:{}\n年龄:{}\n身高:{}\n体重:{}".format(self.name,self.age,self.height,self.weight))
def run(self): # 实例方法
print("人会跑步")
def eat(self):
self.run()
print("人会吃饭")
# 在打印对象时会自动调用__str__ 方法
def __str__(self): # 一定要有返回值
return "<{}>".format(self.name)
keyou = Person("可优",18,1.86,65)
keyou.__init__("lemon",16,1.65,40)
keyou.hair = "杀马特" # 定义属性(不推荐)
print("发型是:{}".format(keyou.hair))
print(obj is keyou) # 用于判断 两个变量 引用对象是否为同一个
print(obj == keyou) # 用于判断引用变量的值是否相等
三 类属性和实例属性
1.概念
- 类属性 就是给类定义的属性
- 通常用来记录这个类相关的特征
- 类属性不会记录具体对象的特征
class Person:
"""
define a person class
"""
head = 1 # 定义类属性
# 实例方法(构造方法)
def __init__(self, name, age, height, weight): # self表示实例方法,实例本身
self.name = name # 实例属性
self.age = age
self.height = height
self.weight = weight
self.head = 2
print("姓名:{}\n年龄:{}\n身高:{}\n体重:{}".format(self.name, self.age, self.height, self.weight))
def run(self): # 实例方法
print("{}会跑步".format(self.name))
def eat(self):
self.run()
print("人会吃饭")
keyou = Person("可优", 18, 1.86, 65)
# 使用对象获取类属性是不推荐的
print("{}有{}个聪明的脑袋".format(keyou.name,keyou.head)) # 先查对象是否有对应的属性,再获取类属性
print("人类有{}个脑袋".format(Person.head))
运行结果:
可优有2个聪明的脑袋
人类有1个脑袋
四 类方法和静态方法
1.类方法
- 类属性就是针对类定义的属性
– 使用赋值语句在class关键字下方可以定义类属性
– 类属性用于记录与这个类相关的特征 - 类方法就是针对类定义的方法
– 在类方法内部可以直接访问类属性或者调用其他的类方法
语法如下:
class Person:
"""
define a person class
"""
head = 1 # 定义类属性
# 实例方法(构造方法)
def __init__(self, name, age, height, weight): # self表示实例方法,实例本身
self.name = name # 实例属性
self.age = age
self.height = height
self.weight = weight
self.head = 2
print("姓名:{}\n年龄:{}\n身高:{}\n体重:{}".format(self.name, self.age, self.height, self.weight))
def run(self): # 实例方法
print("{}会跑步".format(self.name))
def eat(self):
self.run()
print("人会吃饭")
@classmethod
def angry(cls): # 类方法
cls.head = 3 # 修改类属性
@classmethod
def setCountry(cls,country):
cls.country = country # 对类属性进行修改
print("来自{}".format(cls.country))
keyou = Person("可优", 18, 1.86, 65)
keyou.angry() # 通过对象来调用类方法,它不是将对象本身传给cls,而是将对象所属的类传给cls
Person.angry() # 通过类对象引用
keyou.setCountry("成都") # 对类属性进行修改
静态方法
需要通过装饰器@staticmethod 来进行修饰,静态方法不需要多定义参数
class Person:
"""
define a person class
"""
country = "大理"
@staticmethod
def getCountry(): # 静态方法 我们往往把与类相关的函数,放到类当中,作为静态方法,封装性比较好
return Person.country
Person.getCountry()
总结:
从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性,也可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高.静态方法中不需要额外定义参数,因此静态方法中引用类属性的话,必须通过类对象来引用.