1.类与对象
(1).面向对象两个核心概念
1.类:是一群具有相同特征或形为的事物的一个统称,类是抽象的,不能直接使用
2.对象:由类创造出来的具体存在
在开发中,应该先有类,再有对象
(2).类和对象的关系
类是模板,对象是根据这个模板创建出来的
类只需要有一个,对象可以有多个(一张图纸可以造多个飞机)
类:属性(信息)和方法(你能完成的事(动作))
(3)类的三要素
1.类名 :这类事物的名字,满足大驼峰命名法
2.属性:这个类创建出的对象有什么特征
3.方法:这个类创建出的对象有什么行为
例如:
1.需求:
小明今年18岁,身高1.75,每天早上要跑步,然后去吃东西
小美今年17岁,身高1.65,小美不跑步,但是喜欢吃东西
分析:
类名:Person
属性:name,age,height
方法:run(),eat()
2.需求:
一只黄颜色的狗叫大黄,看见生人汪汪叫,看见家人摇尾巴
分析:
类名:Dog
属性:name,color
方法:shout(),shake()
self: 哪一个对象调用的方法,self就是哪一个对象的引用,可以使用 .属性名
利用赋值语句就可以在类的外部给对象增加属性(不推荐),将对象的属性封装在类中
需求:
小猫爱吃鱼 小猫要喝水
代码:
# 定义类
class Cat():
# 定义类的两个方法: eat(),drink()
def eat(self):
# name: 类的属性
print('%s爱吃鱼' %self.name)
def drink(self):
print('%s要喝水' %self.name)
# 创建对象(实例化)
tom = Cat()
# 给tom对象的name属性赋值
tom.name = 'Tom'
# 返回的是一个对象,因为tom是对象
print(tom)
# 调用方法
tom.eat()
tom.drink()
hello_kitty = Cat()
hello_kitty.name='hello_kitty'
hello_kitty.eat()
hello_kitty.drink()
运行结果:
2.初始化方法
__init__方法: 初始化
代码:
class Cat():
# 初始化,name:类的属性
def __init__(self,name):
print('这是一个初始化方法')
# 将传入的参数name赋给类的name属性
self.name = name
def eat(self):
print('%s爱吃鱼' %self.name)
# 创建对象(实例化)
tom = Cat('Tom')
# 查看属性
print(tom.name)
# 调用方法
tom.eat()
hello_kitty = Cat('hello_kitty')
print(hello_kitty.name)
hello_kitty.eat()
运行结果:
3. str方法
__str__方法: 规范化输出
代码:
class Cat():
# 初始化
def __init__(self,name):
self.name = name
# 规范化输出
def __str__(self):
return '我是%s' %self.name
# 创建对象(实例化)
tom = Cat('小淘气')
# 此时输出的便不再是一个对象,而是规范化后的内容
print(tom)
运行结果:
4.面向对象的三大特征
1.封装:根据职责将属性和方法封装到一个抽象的类中,定义类的准则
2.继承:实现代码的重用,相同的代码不需要重复的编写
3.多态:不同的子类,对象调用相同的方法,产生不同的执行结果
(1).封装
封装: 面向对象第一步:将属性和方法封装到一个抽象的类中,外界使用类创建对象,然后让对象调用方法,对象的方法的细节都封装在类的内部.
需求:
1.小明和小美都爱跑步
2.小美体重45.0公斤
3.小明体重75.0公斤
4.每次跑步会减肥0.5公斤
5.每次吃东西会增重1攻击
代码:
class Person():
def __init__(self,name,weight):
self.name = name
self.weight = weight
def __str__(self):
return '我的名字叫%s 体重为%.2f ' %(self.name,self.weight)
def eat(self):
self.weight +=1
print('%s喜欢跑步' %self.name)
def run(self):
self.weight -=0.5
print('%s喜欢吃东西' %self.name)
xiaoming = Person('小明',75.00)
print(xiaoming)
xiaoming.run()
print(xiaoming)
xiaoming.eat()
print(xiaoming)
xiaomei = Person('小美',45.00)
print(xiaomei)
xiaomei.run()
print(xiaomei)
xiaomei.eat()
print(xiaomei)
运行结果:
(2).继承
继承: 实现代码的重用,相同的代码不需要重复的编写
代码1:
# 定义Animal类
class Animal():
# 定义方法
def eat(self):
print('吃~~~~~')
def drink(self):
print('喝~~~~~')
def run(self):
print('跑~~~~~')
def sleep(self):
print('睡~~~~~')
# 继承Animal类; Cat:子类 Animal:父类
class Cat(Animal):
# 定义自己的方法
def call(self):
print('喵~')
# 创建对象(实例化)
fentiao = Cat()
# 由于继承了父类的方法,所以可以调用父类的方法
fentiao.eat()
fentiao.drink()
fentiao.run()
fentiao.sleep()
# 调用自己定义的方法
fentiao.call()
总结:
子类继承自父类,可以直接享受父类中已经封装好的方法
子类重应该根据职责,封装子类特有的属性和方法
运行结果:
代码2:
# 定义Animal类
class Animal():
# 定义方法
def eat(self):
print('吃~~~~~')
def drink(self):
print('喝~~~~~')
def run(self):
print('跑~~~~~')
def sleep(self):
print('睡~~~~~')
# 继承Animal类; Cat:子类 Animal:父类
class Cat(Animal):
# 定义自己的方法
def call(self):
print('喵~')
# 继承Cat类; HelloKitty:子类 Cat:父类
class HelloKitty(Cat):
def speak(self):
print('我能说英语')
# 继承Animal类; Dog:子类 Animal:父类
class Dog(Animal):
def bark(self):
print('汪~')
#创建对象(实例化)
kt = HelloKitty()
# 调用父类的父类的方法
kt.eat()
kt.speak()
总结:
子类可以继承父类的所有属性和方法
继承具有传递性,子类拥有父类的父类的属性和方法
运行结果:
代码3:
# 定义Animal类
class Animal():
# 定义方法
def eat(self):
print('吃~~~~~')
def drink(self):
print('喝~~~~~')
def run(self):
print('跑~~~~~')
def sleep(self):
print('睡~~~~~')
# 继承Animal类; Cat:子类 Animal:父类
class Cat(Animal):
# 定义自己的方法
def call(self):
print('喵~')
# 继承Cat类; HelloKitty:子类 Cat:父类
class HelloKitty(Cat):
def speak(self):
print('我能说英语')
# 重写父类的call方法
def call(self):
print('@#@$@$@#@!#')
kt = HelloKitty()
kt.call()
总结:
如果子类中,重写了父类的方法
在运行中,只会调用在子类中重写的方法而不会调用父类方法
运行结果:
代码4:
# 定义Animal类
class Animal():
def eat(self):
print('吃~~~~~')
def drink(self):
print('喝')
def run(self):
print('跑')
def sleep(self):
print('睡')
# 继承Animal类; Cat:子类 Animal:父类
class Cat(Animal):
def call(self):
print('喵~')
# 继承Cat类; HelloKitty:子类 Cat:父类
class HelloKitty(Cat):
def speak(self):
print('我能说英语')
# 重写父类的call方法
def call(self):
#1.针对子类特有的需求,编写代码
print('@#@$@$@#@!#')
#2.调用原本在父类中封装的方法
# Cat.call(self)
super().call()
kt = HelloKitty()
kt.call()
总结:
# 如果子类中,重写了父类的方法,将不会调用父类的此方法
# 若想要调用父类原有的方法,则需要用到super()
运行结果:
多继承:
多继承:子类具有一个父类叫做单继承,子类拥有多个父类,并且具有所以父类的属性和方法,叫做多继承
例如:孩子会继承父亲和母亲的特性
语法:
class 子类名(父类名1,父类名2,...)
pass
代码:
class A():
def test(self):
print ('test 方法')
class B():
def demo(self):
print ('demo 方法')
class C(A,B):
# 多继承可以让子类对象同时具有多个父类的属性和方法
pass
c=C()
c.test()
c.demo()
class A():
def test(self):
print('A---->test方法')
def demo(self):
print('A---->demo方法')
class B():
def test(self):
print('B---->test方法')
def demo(self):
print('B---->demo方法')
# 当不同的父类拥有不同的方法时,调用时谁在前,就继承谁
class C(A,B):
pass
c = C()
c.test()
c.demo()
运行结果:
(3).多态
多态:不同的子类,对象调用相同的方法,产生不同的执行结果
代码:
class Dog():
def __init__(self, name):
self.name = name
def play(self):
print('%s 蹦蹦跳跳的玩耍' % self.name)
# 继承
class Xiaotianquan(Dog):
def play(self):
print('%s 飞到天上玩耍' % self.name)
# 定义一个人类,让人和狗一起玩耍
class Person():
def __init__(self, name):
self.name = name
def person_with_dog(self, dog): # dog为形参
print('%s 和 %s 一起开心的玩耍' % (self.name, dog.name))
dog.play()
# wangcai = Dog('旺财')
wangcai = Xiaotianquan('旺财')
xiaohua = Person('小花')
# wangcai 与 wangcai = Xiaotianquan('旺财') 联系
xiaohua.person_with_dog(wangcai)
运行结果: