


类和对象概念
类和对象是面向对象的两个核心概念
类
- 类是一个图纸,模板
- 类不能直接使用,相当于设计飞机的时候画的图纸
- 类中行为——方法
- 类的特性——属性
对象
- 根据类制造出来,可以直接使用
- 一个类可以制造多个对象
- 每个对象的属性的值可能有所不同
- 一定先有类,才有对象
面向对象设计的基础
- 面向对象编程首先要设计类
- 类的三个要素
- 类名
- 属性
- 类中的变量——属性
- 方法
- 类中的函数——方法
- 设计一个小猫类
- 类名cat
- 属性
- name(名字)
- color(颜色)
- height(身高)
- weight(体重)
- sex(性别)
- 方法
- eat(吃)
- drink(喝)
- sleep(睡)
- …
class关键字
- 定义一个类
- 语法
class 类名:
def 方法名(self,参数1,参数2,......)
pass
# coding: utf-8
class cat:
def eat(self):
print('吃饭')
def drink(self):
print('喝水')
对象
- 类中的方法不能直接调用
- 把类实例化为对象后,通过对象调用的方法
- 实例
- 通过类创建的对象,叫类的实例
- 实例化
- 创建对象的动作,叫实例化
- 语法
对象名 = 类名(参数列表)
# 对象创建后通过对象名.方法名(参数),调用方法
对象名.方法1()
# coding: utf-8
class cat: # 定义了一个类 cat ,这个类不能直接使用
def eat(self): # 第一个参数必须是self
print('吃饭')
def drink(self):
print('喝水')
c1=cat() # 根据类cat 创建一个对象c1,对象名类似变量名
c1.eat() # 调用的时候,不需要提供self对应的实参
c1.drink() # 调用对象的发法
# 方法只能通过对象调用,不能通过类直接调用
# c1就是类 cat 的实例
# c1=cat 这个动作就叫实例化
c2=cat # 实例化,实例化的结果是cat 类有一个对象叫c2
# c2 是类cat 的实例
self参数的作用
- self 可以在方法内部定义和使用属性
- self 可以在方法内部嵌套调用其他方法
- 在类的外部,是不能使用self的
- 在类的外部调用方法
- 对象名.方法名
- 在类的外部使用属性
- 对象名.属性名
# coding: utf-8
class cat: # 定义了一个类 cat ,这个类不能直接使用
def set_name(self):
self.name='tom' # 定义了一个属性,名叫name ,值是tom
def eat(self): # 第一个参数必须是self
print('%s吃饭'% self.name) # 在使用name属性
def drink(self):
print('%s喝水'% self.name) # 在使用name 属性
def demo(self): # 只是为了举例,在类的内部,方法嵌套调用
self.eat()
self.drink()
c=cat()
c.set_name()
c.drink()
c.eat()
c.name='修勾'
c.drink()
c.eat()
c.demo()
练习


# coding: utf-8
class dog:
def set_name(self, name):
self.name = name
def show_name(self):
print(self.name)
d=dog()
d.set_name('旺财')
d.show_name()
init方法
- __ init __,前后各两个下划线
- 当创建对象的时候,也就是实例化对象的时候,init自动调用
# coding: utf-8
class cat:
def __init__(self):
print('cat被创建')
def eat(self):
print('小猫吃鱼')
c=cat() # 实例化对象的时候,init方法自动调用
c.eat() # 必须明确通过代码调用普通方法
Init方法的作用
- 定义类中的属性
- 同时通过init方法的参数为属性赋值
- init方法一旦有实参,对象实例化的时候就必须提供实参
- 为了避免实例化的时候必须提供实参,init的形参总是有缺省值

# coding: utf-8
# class cat: # 不在普通方法中定义属性
# def set_name(self,name):
# self.name=name
# def show_name(self):
# print(self.name)
class cat:
def __init__(self,name='tom'):
self.name=name
def set_name(self,name):
self.name=name
def show_name(self):
print(self.name)
c=cat('yoyo') # init以及自动调用,name属性有了
c.show_name()
- 如果init有形参,那么实例化对象的时候,必须提供实参
# coding: utf-8
class cat:
def __init__(self,name):
pass
c=cat('tom') # 如果init有形参,那么实例化对象的时候,必须提供实参
# coding: utf-8
# 汽车 car 要区分属性和方法,在init方法中为每个属性定义默认值
# 属性
# luntai(轮胎)
# yanse(颜色)
# chuanghu(窗户)
# xinghao(型号)
# 方法
# guadang(挂挡)
# qianjin(前进)
# houtui(后退)
# wurenjiashi(无人驾驶)
# shache(刹车)
# jiayou(加油)
class car:
def __init__(self, luntai='轮胎', yanse='白色', chuanghu='黑色', xinghao='大众'):
self.luntai = luntai
self.yanse = yanse
self.chuanghu = chuanghu
self.xinghao = xinghao
def guadang(self, a='前进'):
self.jiayou()
if a == '前进':
self.qianjin()
elif a == '后退':
self.houtui()
else:
print('错')
def qianjin(self):
print('%s在前进'% self.xinghao)
def houtui(self):
print('%s在后退'% self.xinghao)
def wurenjiashi(self):
print('无人驾驶')
def shache(self):
print('刹车')
def jiayou(self):
print('加油')
c = car
c.guadang('前进')
__ del__方法
- 当对象在内存中销毁的时候,自动调用del方法
- del方法只有一个参数self
# coding: utf-8
class cat:
def __init__(self, name='yoyo'):
self.name = name
def show_name(self):
print(self.name)
def __del__(self):
print('%s销毁' % self.name)
c=cat() # c是个对象,同时也是个变量
c.show_name() # 显示了yoyo
如果对象是局部的,那么函数执行完毕,自动调用对象的del方法
如果对象是全局的,那么程序执行完毕,自动调用对象的方法
# coding: utf-8
class cat:
def __init__(self, name='yoyo'):
self.name = name
def show_name(self):
print(self.name)
def __del__(self):
print('%s销毁' % self.name)
def mt_test1():
c1=cat('tom')
c1.show_name()
mt_test1()
c=cat() # c是个对象,同时也是个变量
c.show_name() # 显示了yoyo
- __ init __ 不要写成__ int__
- __ del __ 对象在内存中销毁的时候自动调用del
- 不要理解成调用del 是把对象从内存中删除了
- 对象即使没有del ,同样会被销毁
- 当对象从内存中销毁的时候,有机会能执行一些代码
设计方法的惯例
(有返回值的方法)
# coding: utf-8
class cat:
def __init__(self, name='tom'):
self.name = name
# 不想写show_name方法,只是把name返回给调用者
def get_name(self): # 设计方法管理,得到属性值get_属性名
return self.name
def set_name(self,name): # set_属性名(self,形参)
self.name = name
def show_name(self): # 在方法中显示属性的值一般show_属性名
print(self.name)
c = cat()
print(c.get_name())
print(c.show_name()) # 没有return 语句的方法或者函数不要放到print
c1 = cat('yoyo')
c1.set_name('加菲')
print(c1.get_name())
练习-设计小狗类

# coding: utf-8
class dog():
def __init__(self, name='金毛', age=3):
self.name = name
self.age = age
def set_name(self,name):
self.name=name
def get_name(self):
return self.name
def show_name(self):
print(self.name)
def set_age(self, age):
self.age = age
def get_age(self):
return self.age
def show_age(self):
print(self.age)
d=dog('德牧',2) # 实例化的时候设置的属性值
print(d.get_name())
d.set_name('二哈') # 实例化以后再设置属性值
print(d.get_name())
d.show_name()
__ str __ 方法
- __ str __
- 只有self,没有其他参数
- 必须有return,return必须返回一个字符串
- str 方法的作用
- 当有一个带有str 方法的对象放到print 里面,print函数会显示str 方法return 返回的字符串
- 如果类没有str方法,那么类实例化的对象放到print里面显示的是对象的内存地址
# coding: utf-8
class cat():
def __init__(self):
pass
c = cat()
print(c) # 对象直接放到print里,显示的是对象内存的地址编号
# 假设:设计一个对象,放到print里面,显示对象name的属性值
class demo():
def __init__(self, name='demo'):
self.name = name
def __str__(self):
return self.name
d = demo()
print(d)

# coding: utf-8
class dog:
def __str__(self):
return '这是一个小狗类对象'
d=dog()
print(d)
类设计练习
类设计实例演示-计算机

# coding: utf-8
class calc:
def __init__(self,oper='+'):
self.oper=oper
def calc(self,a,b):
if self.oper=='+':
return a+b
elif self.oper=='-':
return a-b
elif self.oper=='*':
return a*b
elif self.oper=='/':
if b!=0:
return a/b
else:
return None
else:
return None
a=calc()
print(a.calc(3,4))
b=calc('*')
print(b.calc(3,4))
c=calc('/')
print(c.calc(3,0))
e=calc('sfev')
print(e.calc(3,4))
练习

# cdoing: utf-8
class coder:
def work(self):
print('工作')
def sleep(self):
print('睡觉')
c=coder()
c.work()
c.sleep()

class coder:
def __init__(self):
self.name = '张三'
self.age = 30
self.sex = '男'
c = coder()
print(c.name)
print(c.age)
print(c.sex)

class coder:
def __del__(self):
print('再见程序员')
c=coder()
面向对象三大特性
- 封装
- 继承
- 多态
封装
- 就是把类的属性和方法封装到类的内部,只能在内部使用,不能在类的外部使用
- 把属性和方法名前面加两个下划线__, 这个属性和方法就成了类的私有属性和方法
# coding: utf-8
class woman:
def __init__(self):
self.name='玛丽'
self.__weight=200 # __weight 是一个私有属性
def __eat(self): # __eat 方法为私有方法
print('吃的多')
w=woman()
print(w.name)
# print(w.__weight) 不能在类的外部访问类的私有属性
# w.eat() 不能在类的外部调用私有方法
练习

# coding: utf-8
class user:
def __init__(self):
self.name='张三'
self.__passwd='123456'
def show_name(self):
print(self.name)
def __show_passwd(self):
print(self.__passwd)
u=user()
u.show_name()
# u.__show_passwd() 类的外部不能访问类的私有属性和方法
继承
- 类A继承自类B,类A会拥有类B的所有属性和方法
- 语法
class A :
pass
class B(A): # B继承自类A
# coding: utf-8
class animal:
def sleep(self):
print('睡')
def eat(self):
print('吃')
class dog(animal): # 类dog继承自animal类
def run(self):
print('跑')
d=dog() # dog类会拥有animal 所有属性和方法
d.sleep()
d.eat()
d.run()
专业术语
- 子类–派生类
- dog是animal的子类
- dog是animal的派生类
- 父类–基类
- animal是dog的父类
- animal是dog的基类
- 继承–派生
- dog类继承自animal
- dog类派生自animal
- 一个父类可以有多个子类继承,每个子类可以有自己特有的方法和属性
# coding: utf-8
class animal:
def sleep(self):
print('睡')
def eat(self):
print('吃')
class dog(animal):
def run(self):
print('跑')
class fish(animal):
def swimming(self):
print('游')
class bird(animal):
def fly(self):
print('飞')
针对animal类,dog ,bird 和 fish类是说明

多级继承
- 类C继承自类B,类B继承自类A
- 类C就拥有了类B和类A的所有属性和方法
# coding: utf-8
class animal:
def sleep(self):
print('睡')
def eat(self):
print('吃')
class dog(animal):
def run(self):
print('跑')
class jinmao(dog):
def keai(self):
print("萌")
d=jinmao ()
d.sleep()
d.eat()
d.run()
d.keai()


方法重写
- 父类的方法不能满足子类的需求
- 方法重写有两种方式
- 覆盖父类方法
- 扩展父类方法
覆盖父类方法
- 在子类中出现和父类相同的方法,那么在子类中相同方法会把父类的方法覆盖
# coding: utf-8
class animal:
def sleep(self):
print('睡')
def eat(self):
print('吃')
class dog(animal):
def eat(self): #出现和父类同名方法,在子类dog中,就没有父类eat 方法
print('吃肉')
d = dog()
d.sleep()
d.eat() # 由于覆盖了父类的eat 方法,所以这里调用的是dog的eat方法

扩展父类方法
- 如果父类的方法不能完全满足子类需求,子类可以在父类方法基础上增加功能
- 语法
1、在子类中实现和父类同名方法
2、在子类的同名方法中用super().父类同名方法 来调用父类的方法
# coding: utf-8
class animal:
def sleep(self):
print('睡')
def eat(self):
print('吃')
class dog(animal):
def sleep(self):
super().sleep() # 在子类的方法中调用父类的sleep 方法
print('睡得多')
d=dog()
d.eat()
d.sleep() # 扩展了父类的sleep,所以既执行了父类的sleep,又增加了功能

父类的私有成员不会继承给子类
- 父类中所有的私有方法和私有属性归父类特有,子类不能继承
# coding: utf-8
class animal:
def sleep(self):
print('睡')
def __eat(self): # 私有成员不会被子类继承
print('吃')
class dog(animal): # 在dog里面没有__eat方法
pass
d=dog()
d.sleep()
# d.__eat() 这的代码会出错
练习-father类和继承


# coding: utf-8
class father:
def __init__(self):
self.__name = '张三'
self.house='别墅'
def eat(self):
print('吃')
def sleep(self):
print('睡')
def __edu_back(self):
print('本科')
class son(father):
def show_eat(self):
self.eat() # eat 是继承自father的,但也是son自己
def show_sleep(self):
self.sleep()
def show_house(self):
print(self.house) # house是一个属性,不能调用,要用print
s=son()
s.show_eat()
s.show_sleep()
s.show_house()
# father 有两个属性,三个方法
# son 继承了father一个属性,两个方法

多态
- 不同的子类,调用相同的父类方法,产生不同的结果
- 多态的前提,不同的子类来自相同的一个父类,子类会覆盖父类的方法

# coding: utf-8
class animal:
def food(self):
pass
def eat(self):
self.food()
class dog(animal):
def food(self):
print('吃肉')
class sheep(animal):
def food(self):
print('吃草')
d=dog()
d.eat()
s=sheep()
s.eat()
类属性
- 定义在类里面,方法外面,定义的时候不需要self关键字,语法类似于定义普通变量
- 不要把类实例化为对象,直接通过类名.属性名 使用
# coding: utf-8
class dog:
name='二哈' # 如果在这个位置定义的变量,就是类属性
def __init__(self):
pass
print(dog.name) # 显示类属性的值
dog.name='金毛' # 修改类属性的值
print(dog.name)
类方法
- 类方法不能把类实例化为对象,通过类名.类方法名调用
- 用@classmethod来修饰的方法,就是类方法
- 类方法的一个参数是cls(不是self)
- 在类方法内部如果使用类属性,cls.类属性名
- 类方法内部不能使用普通属性,也不能调用普通方法
- 因为类方法不需要对象,但普通方法和普通属性一定需要通过对象调用
# coding: utf-8
class dog:
name='二哈' # 如果在这个位置定义的变量,就是类属性
@classmethod
def set_name(cls,name):
cls.name=name # 通过类方法的形参修改类属性name的值
def __init__(self):
self.age=20 # 在类方法里面无法访问age
def demo(self): # 在类方法中无法调用demo
print('普通方法')
print(dog.name) # 显示类属性的值
dog.name='金毛' # 修改类属性的值
print(dog.name)
dog.set_name('德牧')
print(dog.name)
练习-类属性和类方法
# coding: utf-8
class dog:
name='小白'
@classmethod
def get_name(cls):
return cls.name
def __init__(self):
self.age=0
def get_age(self):
return self.age
# 把类属性name的值改为‘小小白’
dog.name='小小白'
# 调用类方法get_name,显示name的值
print(dog.get_name())
# 要把普通属性age的值修改为10
d=dog()
d.age=10
# 调用普通方法get_age显示age的值
print(d.get_age())

在普通方法中使用类属性和类方法
- 普通方法中通过 类名.类属性或者 类名.类方法使用类属性和类方法
# coding: utf-8
class dog:
name='小白' # 一个类属性
@classmethod
def get_name(cls): # 一个类方法
return cls.name
def demo(self): # 演示如何在普通方法中使用类属性和类方法 (普通方法)
dog.name='小小白' # 类名.属性名 改变了类型的值
print(dog.get_name()) # 类名.类方法 来调用
d=dog()
d.demo()
一个类实例化次数
# coding: utf-8
class dog:
index = 0 # 定义了一个类属性
@classmethod
def count(cls): # 返回值为类属性indedx
return cls.index
def __init__(self): # 实例化的时候自动调用init
dog.index += 1 # 每次实例化的时候类属性 index + 1
d1=dog()
d2=dog()
d3=dog()
d4=dog()
print(dog.count())

静态方法
- 在类中通过 @staticmethod 修饰的方法
- 静态方法不需要实例化为对象,通过类名.静态方法名 调用
- 静态方法不能访问类中的其他成员,静态方法就是一个独立与类存在的函数
# coding: utf-8
class dog:
@staticmethod
def help():
print('这是个静态方法')
dog.help()
静态方法使用场景
- 当代码量特别大的时候,函数也会特别多,为了避免函数的重名,可以把同名函数放到不同的类里面,作为静态方法
- 避免由于函数重名带来错误
# coding: utf-8
class dog:
@staticmethod
def help():
print('这是个静态方法')
class A:
@staticmethod
def help():
print('这是第二个静态方法help')
dog.help()
A.help()
object类(了解)
- 在python3中,如果一个类定义的时候,没有明确的写父类,那么父类就是object
- object 类是python内部自带的
- 如果是python2,那么如果一个类没有写父类,就是没有父类,就不会自动继承自object
# coding: utf-8
class animal: # 如果定义了一个类,没明确的写父类,那么父类就是object
def sleep(self):
print('睡')
# class animal(object):
# def sleep(self):
# print('睡')
a=animal()
a.sleep()
本文介绍了Python中的面向对象编程,包括类和对象的概念,类的三大要素,以及init、__del__和__str__方法。详细讲解了封装、继承和多态等面向对象的特性,并通过实例展示了如何设计和使用类,包括类属性、类方法和静态方法。最后提到了object类在Python中的作用。
3175

被折叠的 条评论
为什么被折叠?



