1.类和对象
1)类的定义
定义:是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用
特征 被称为 属性。
行为 被称为 方法
2)对象的定义
定义:对象是由类创建出来的一个具体存在,可以直接使用。
由 哪一个类创建出来的对象,就拥有在哪一个类中定义的属性和方法。
3)类和对象的关系
类是模板,对象 是根据 类 这个模板创建出来的,应该 先有类,再有对象。
类 只有一个,而 对象 可以有很多个(注意:不同的对象 之间 属性 可能会各不相同)。
类 中定义了什么 属性和方法,对象 中就有什么属性和方法,不可能多,也不可能少。
4)类的设计
类名 这类事物的名字,满足大驼峰命名法(注意:每一个单词的首字母大写,单词与单词之间没有下划线)
属性 这类事物具有什么样的特征
方法 这类事物具有什么样的行为
2.第一个面向对象案列
代码1
解析:创建了一个Dog类,Dog类里面有两个函数(也称方法),然后通过创建Dog的对象wang,调用类里面的方法,完成输出。
class Dog:
def eat(self):
print("狗啃骨头")
def drink(self):
print("狗喝水")
# 创建狗对象
wang = Dog()
wang.eat()
wang.drink()
print(wang)
#打印狗这个对象的地址
addr = id(wang)
print("%x" % addr)
输出:
代码2
同样我们可以创建多个对象,来调用类的方法。可以从输出的两个对象的地址不同,判断创建了两个对象。
class Dog:
def eat(self):
print("狗啃骨头")
def drink(self):
print("狗喝水")
# 创建狗1对象
wang1 = Dog()
wang1.eat()
wang1.drink()
print(wang1)
#打印狗1这个对象的地址
addr1 = id(wang1)
print("%x" % addr1)
# 创建狗2对象
wang2 = Dog()
wang2.eat()
wang2.drink()
print(wang2)
#打印狗2这个对象的地址
addr2 = id(wang2)
print("%x" % addr2)
输出:
3.设置对象属性
代码:
class Cat:
def eat(self):
# 哪一个对象调用的方法,self就是哪一个对象的引用
print("%s 爱吃鱼" % self.name)
def drink(self):
print("%s 要喝水" % self.name)
# 创建猫对象
tom = Cat()
# 可以使用 .属性名 利用赋值语句就可以了
tom.name = "Tom"
tom.eat()
tom.drink()
print(tom)
# 再创建一个猫对象
lazy_cat = Cat()
lazy_cat.name = "大懒猫"
lazy_cat.eat()
lazy_cat.drink()
print(lazy_cat)
输出:
注意:如果在设置属性之前,就先调用函数,则会出错。
代码:
# 创建猫对象
tom = Cat()
# 可以使用 .属性名 利用赋值语句就可以了
# tom.name = "Tom" #放到函数的后面
tom.eat()
tom.drink()
tom.name = "Tom"
print(tom)
输出:
4.init初始化方法
使用类名()创建对象的时候,会自动调用初始化方法
init
代码:
class Cat:
def __init__(self):
print("这是一个初始化方法")
# self.属性名 = 属性的初始值
self.name = "Tom"
def eat(self):
print("%s 爱吃鱼" % self.name)
tom = Cat()
print(tom.name)
输出:
5.利用参数设置属性初始值
代码:
class Cat:
def __init__(self, new_name):
print("这是一个初始化方法")
self.name = new_name
def eat(self):
print("%s 爱吃鱼" % self.name)
tom = Cat("Tom")
tom.eat()
lazy_cat = Cat("大懒猫")
lazy_cat.eat()
输出:
6.del方法
代码:
class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 来了" % self.name)
def __del__(self):
print("%s 我去了" % self.name)
# tom 是一个全局变量
tom = Cat("Tom")
print(tom.name)
# del 关键字可以删除一个对象
del tom
# print(tom)# 出错
输出:
7.str方法
直接打印对象的名字,如果这个类里面重写str方法,则打印对象的名字,则会调用str方法返回的字符串。
代码:
class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 来了" % self.name)
def __str__(self):
# 必须返回一个字符串
return "我是小猫[%s]" % self.name
# tom 是一个全局变量
tom = Cat("汤姆")
print(tom)
输出:
8.封装(跑步案列)
封装 是面向对象编程的一大特点
面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中
外界 使用 类 创建 对象,然后 让对象调用方法
对象方法的细节 都被 封装 在 类的内部
代码:
class Person:
def __init__(self, name, weight):
# self.属性 = 形参
self.name = name
self.weight = weight
def __str__(self):
return "我的名字叫 %s 体重是 %.2f 公斤" % (self.name, self.weight)
def run(self):
print("%s 爱跑步,跑步锻炼身体" % self.name)
self.weight -= 0.5
def eat(self):
print("%s 是吃货,吃完这顿再减肥" % self.name)
self.weight += 1
xiaoming = Person("小明", 75.0)
xiaoming.run()
xiaoming.eat()
print(xiaoming)
# 小美爱跑步
xiaomei = Person("小美", 45)
xiaomei.eat()
xiaomei.run()
print(xiaomei)
print(xiaoming)
输出:
9.封装(家具案例)
代码:
class HouseItem:
def __init__(self, name, area):
self.name = name
self.area = area
def __str__(self):
return "[%s] 占地 %.2f" % (self.name, self.area)
class House:
def __init__(self, house_type, area):
self.house_type = house_type
self.area = area
# 剩余面积
self.free_area = area
# 家具名称列表
self.item_list = []
def __str__(self):
# Python 能够自动的将一对括号内部的代码连接在一起
return ("户型:%s\n总面积:%.2f[剩余:%.2f]\n家具:%s"
% (self.house_type, self.area,
self.free_area, self.item_list))
def add_item(self, item):
print("要添加 %s" % item)
# 1. 判断家具的面积
if item.area > self.free_area:
print("%s 的面积太大了,无法添加" % item.name)
return
# 2. 将家具的名称添加到列表中
self.item_list.append(item.name)
# 3. 计算剩余面积
self.free_area -= item.area
# 1. 创建家具
bed = HouseItem("席梦思", 40)
chest = HouseItem("衣柜", 2)
table = HouseItem("餐桌", 20)
print(bed)
print(chest)
print(table)
# 2. 创建房子对象
my_home = House("两室一厅", 60)
my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print(my_home)
输出:
10.私有属性和方法
在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法。但是我们可以借助这个类的其他非私有方法来访问私有方法和属性。
代码:
class Women:
def __init__(self, name):
self.name = name
self.__age = 18
def __secret(self):
# 在对象的方法内部,是可以访问对象的私有属性的
print("%s 的年龄是 %d" % (self.name, self.__age))
def open_secret(self):
self.__secret()
xiaofang = Women("小芳")
xiaofang.open_secret()
# 私有属性,在外界不能够被直接访问
# print(xiaofang.__age)
# 私有方法,同样不允许在外界直接访问
# xiaofang.__secret()
输出:
也可以使用另外一种方法来访问私有属性和方法
代码:
class Women:
def __init__(self, name):
self.name = name
self.__age = 18
def __secret(self):
# 在对象的方法内部,是可以访问对象的私有属性的
print("%s 的年龄是 %d" % (self.name, self.__age))
xiaofang = Women("小芳")
# 伪私有属性,在外界不能够被直接访问
print(xiaofang._Women__age)
# 伪私有方法,同样不允许在外界直接访问
xiaofang._Women__secret()
输出:
结束!下一章节讲解面向对象的继承、多态和接口。